uint64_t iax2_format_compatibility_cap2bitfield(const struct ast_format_cap *cap) { uint64_t bitfield = 0; int x; for (x = 0; x < ast_format_cap_count(cap); x++) { struct ast_format *format = ast_format_cap_get_format(cap, x); bitfield |= ast_format_compatibility_format2bitfield(format); ao2_ref(format, -1); } return bitfield; }
/*! \brief Add format/lang pairs to the array embedded in the sound object */ static int add_format_information_cb(void *obj, void *arg, int flags) { char *language = obj; struct lang_format_info *args = arg; int idx; RAII_VAR(struct ast_format_cap *, cap, NULL, ao2_cleanup); RAII_VAR(struct ast_media_index *, sounds_index, ast_sounds_get_index(), ao2_cleanup); if (!sounds_index) { return CMP_STOP; } cap = ast_media_get_format_cap(sounds_index, args->filename, language); if (!cap) { return CMP_STOP; } for (idx = 0; idx < ast_format_cap_count(cap); idx++) { struct ast_format *format = ast_format_cap_get_format(cap, idx); struct ast_json *lang_format_pair; if (!ast_strlen_zero(args->format_filter) && strcmp(args->format_filter, ast_format_get_name(format))) { ao2_ref(format, -1); continue; } lang_format_pair = ast_json_pack("{s: s, s: s}", "language", language, "format", ast_format_get_name(format)); if (!lang_format_pair) { ao2_ref(format, -1); return CMP_STOP; } ast_json_array_append(args->format_list, lang_format_pair); ao2_ref(format, -1); } return 0; }
static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream) { RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, peer, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup); enum ast_media_type media_type = stream_to_media_type(session_media->stream_type); struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT; int fmts = 0; int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) && ast_format_cap_count(session->direct_media_cap); int dsp_features = 0; if (!(caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) || !(peer = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) || !(joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", session_media->stream_type); return -1; } /* get the endpoint capabilities */ if (direct_media_enabled) { ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps); format_cap_only_type(caps, media_type); } else { ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type); } /* get the capabilities on the peer */ get_codecs(session, stream, &codecs, session_media); ast_rtp_codecs_payload_formats(&codecs, peer, &fmts); /* get the joint capabilities between peer and endpoint */ ast_format_cap_get_compatible(caps, peer, joint); if (!ast_format_cap_count(joint)) { struct ast_str *usbuf = ast_str_alloca(256); struct ast_str *thembuf = ast_str_alloca(256); ast_rtp_codecs_payloads_destroy(&codecs); ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n", session_media->stream_type, ast_format_cap_get_names(caps, &usbuf), ast_format_cap_get_names(peer, &thembuf)); return -1; } ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp), session_media->rtp); ast_format_cap_append_from_cap(session->req_caps, joint, AST_MEDIA_TYPE_UNKNOWN); if (session->channel) { ast_channel_lock(session->channel); ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_remove_by_type(caps, media_type); ast_format_cap_append_from_cap(caps, joint, media_type); /* * Apply the new formats to the channel, potentially changing * raw read/write formats and translation path while doing so. */ ast_channel_nativeformats_set(session->channel, caps); if (media_type == AST_MEDIA_TYPE_AUDIO) { ast_set_read_format(session->channel, ast_channel_readformat(session->channel)); ast_set_write_format(session->channel, ast_channel_writeformat(session->channel)); } if ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) && (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833) && (session->dsp)) { dsp_features = ast_dsp_get_features(session->dsp); dsp_features &= ~DSP_FEATURE_DIGIT_DETECT; if (dsp_features) { ast_dsp_set_features(session->dsp, dsp_features); } else { ast_dsp_free(session->dsp); session->dsp = NULL; } } ast_channel_unlock(session->channel); } ast_rtp_codecs_payloads_destroy(&codecs); return 0; }
int ooh323c_set_capability_for_call (ooCallData *call, struct ast_format_cap *cap, int dtmf, int dtmfcodec, int t38support, int g729onlyA) { int ret = 0, x, txframes; if (gH323Debug) { ast_verb(0, "\tAdding capabilities to call(%s, %s)\n", call->callType, call->callToken); } if(dtmf & H323_DTMF_CISCO || 1) ret |= ooCallEnableDTMFCISCO(call,dtmfcodec); if(dtmf & H323_DTMF_RFC2833 || 1) ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec); if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1) ret |= ooCallEnableDTMFH245Alphanumeric(call); if(dtmf & H323_DTMF_H245SIGNAL || 1) ret |= ooCallEnableDTMFH245Signal(call); if (t38support) ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX, &ooh323c_start_receive_datachannel, &ooh323c_start_transmit_datachannel, &ooh323c_stop_receive_datachannel, &ooh323c_stop_transmit_datachannel, 0); for(x=0; x<ast_format_cap_count(cap); x++) { struct ast_format *format = ast_format_cap_get_format(cap, x); if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 ulaw capability to call(%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 alaw capability to call(%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726 capability to call (%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret = ooCallAddG726Capability(call, OO_G726, txframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726aal2 capability to call (%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { txframes = (ast_format_cap_get_format_framing(cap, format))/10; if (gH323Debug) { ast_verb(0, "\tAdding g729A capability to call(%s, %s)\n", call->callType, call->callToken); } ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (g729onlyA) continue; if (gH323Debug) { ast_verb(0, "\tAdding g729 capability to call(%s, %s)\n", call->callType, call->callToken); } ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (gH323Debug) { ast_verb(0, "\tAdding g729B capability to call(%s, %s)\n", call->callType, call->callToken); } ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g7231 capability to call (%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding h263 capability to call (%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding gsm capability to call(%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding Speex capability to call(%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } ao2_ref(format, -1); } return ret; }
int ooh323c_set_capability (struct ast_format_cap *cap, int dtmf, int dtmfcodec) { int ret = 0, x; if (gH323Debug) { ast_verb(0, "\tAdding capabilities to H323 endpoint\n"); } for(x=0; x<ast_format_cap_count(cap); x++) { struct ast_format *format = ast_format_cap_get_format(cap, x); if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 ulaw capability to H323 endpoint\n"); } ret= ooH323EpAddG711Capability(OO_G711ULAW64K, gtxframes, grxframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 alaw capability to H323 endpoint\n"); } ret= ooH323EpAddG711Capability(OO_G711ALAW64K, gtxframes, grxframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g729A capability to H323 endpoint\n"); } ret = ooH323EpAddG729Capability(OO_G729A, 2, 24, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (gH323Debug) { ast_verb(0, "\tAdding g729 capability to H323 endpoint\n"); } ret |= ooH323EpAddG729Capability(OO_G729, 2, 24, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (gH323Debug) { ast_verb(0, "\tAdding g729b capability to H323 endpoint\n"); } ret |= ooH323EpAddG729Capability(OO_G729B, 2, 24, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g7231 capability to H323 endpoint\n"); } ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726 capability to H323 endpoint\n"); } ret = ooH323EpAddG726Capability(OO_G726, gtxframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726aal2 capability to H323 endpoint\n"); } ret = ooH323EpAddG726Capability(OO_G726AAL2, gtxframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding h263 capability to H323 endpoint\n"); } ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding gsm capability to H323 endpoint\n"); } ret = ooH323EpAddGSMCapability(OO_GSMFULLRATE, 4, FALSE, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding speex capability to H323 endpoint\n"); } ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } ao2_ref(format, -1); } if(dtmf & H323_DTMF_CISCO) ret |= ooH323EpEnableDTMFCISCO(0); if(dtmf & H323_DTMF_RFC2833) ret |= ooH323EpEnableDTMFRFC2833(0); else if(dtmf & H323_DTMF_H245ALPHANUMERIC) ret |= ooH323EpEnableDTMFH245Alphanumeric(); else if(dtmf & H323_DTMF_H245SIGNAL) ret |= ooH323EpEnableDTMFH245Signal(); return ret; }
static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream) { RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, peer, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup); enum ast_media_type media_type = stream_to_media_type(session_media->stream_type); struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT; int fmts = 0; int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) && ast_format_cap_count(session->direct_media_cap); if (!(caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) || !(peer = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) || !(joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", session_media->stream_type); return -1; } /* get the endpoint capabilities */ if (direct_media_enabled) { ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps); format_cap_only_type(caps, media_type); } else { ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type); } /* get the capabilities on the peer */ get_codecs(session, stream, &codecs); ast_rtp_codecs_payload_formats(&codecs, peer, &fmts); /* get the joint capabilities between peer and endpoint */ ast_format_cap_get_compatible(caps, peer, joint); if (!ast_format_cap_count(joint)) { struct ast_str *usbuf = ast_str_alloca(64); struct ast_str *thembuf = ast_str_alloca(64); ast_rtp_codecs_payloads_destroy(&codecs); ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n", session_media->stream_type, ast_format_cap_get_names(caps, &usbuf), ast_format_cap_get_names(peer, &thembuf)); return -1; } ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp), session_media->rtp); ast_format_cap_append_from_cap(session->req_caps, joint, AST_MEDIA_TYPE_UNKNOWN); if (session->channel) { struct ast_format *fmt; ast_channel_lock(session->channel); ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_remove_by_type(caps, media_type); /* * XXX Historically we picked the "best" joint format to use * and stuck with it. It would be nice to just append the * determined joint media capabilities to give translation * more formats to choose from when necessary. Unfortunately, * there are some areas of the system where this doesn't work * very well. (The softmix bridge in particular is reluctant * to pick higher fidelity formats and has a problem with * asymmetric sample rates.) */ fmt = ast_format_cap_get_format(joint, 0); ast_format_cap_append(caps, fmt, 0); /* * Apply the new formats to the channel, potentially changing * raw read/write formats and translation path while doing so. */ ast_channel_nativeformats_set(session->channel, caps); ast_set_read_format(session->channel, ast_channel_readformat(session->channel)); ast_set_write_format(session->channel, ast_channel_writeformat(session->channel)); ast_channel_unlock(session->channel); ao2_ref(fmt, -1); } ast_rtp_codecs_payloads_destroy(&codecs); return 0; }
static int native_rtp_bridge_compatible_check(struct ast_bridge *bridge, struct ast_bridge_channel *bc0, struct ast_bridge_channel *bc1) { enum ast_rtp_glue_result native_type; struct ast_rtp_glue *glue0; struct ast_rtp_glue *glue1; RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup); RAII_VAR(struct ast_rtp_instance *, instance1, NULL, ao2_cleanup); RAII_VAR(struct ast_rtp_instance *, vinstance0, NULL, ao2_cleanup); RAII_VAR(struct ast_rtp_instance *, vinstance1, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, cap0, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, cap1, NULL, ao2_cleanup); int read_ptime0; int read_ptime1; int write_ptime0; int write_ptime1; if (!native_rtp_bridge_capable(bc0->chan)) { ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n", bridge->uniqueid, ast_channel_name(bc0->chan)); return 0; } if (!native_rtp_bridge_capable(bc1->chan)) { ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n", bridge->uniqueid, ast_channel_name(bc1->chan)); return 0; } native_type = native_rtp_bridge_get(bc0->chan, bc1->chan, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1); if (native_type == AST_RTP_GLUE_RESULT_FORBID) { ast_debug(1, "Bridge '%s' can not use native RTP bridge as it was forbidden while getting details\n", bridge->uniqueid); return 0; } if (ao2_container_count(bc0->features->dtmf_hooks) && ast_rtp_instance_dtmf_mode_get(instance0)) { ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n", bridge->uniqueid, ast_channel_name(bc0->chan)); return 0; } if (ao2_container_count(bc1->features->dtmf_hooks) && ast_rtp_instance_dtmf_mode_get(instance1)) { ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n", bridge->uniqueid, ast_channel_name(bc1->chan)); return 0; } if (native_type == AST_RTP_GLUE_RESULT_LOCAL && (ast_rtp_instance_get_engine(instance0)->local_bridge != ast_rtp_instance_get_engine(instance1)->local_bridge || (ast_rtp_instance_get_engine(instance0)->dtmf_compatible && !ast_rtp_instance_get_engine(instance0)->dtmf_compatible(bc0->chan, instance0, bc1->chan, instance1)))) { ast_debug(1, "Bridge '%s' can not use local native RTP bridge as local bridge or DTMF is not compatible\n", bridge->uniqueid); return 0; } cap0 = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); cap1 = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); if (!cap0 || !cap1) { return 0; } /* Make sure that codecs match */ if (glue0->get_codec) { glue0->get_codec(bc0->chan, cap0); } if (glue1->get_codec) { glue1->get_codec(bc1->chan, cap1); } if (ast_format_cap_count(cap0) != 0 && ast_format_cap_count(cap1) != 0 && !ast_format_cap_iscompatible(cap0, cap1)) { struct ast_str *codec_buf0 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); struct ast_str *codec_buf1 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); ast_debug(1, "Bridge '%s': Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n", bridge->uniqueid, ast_format_cap_get_names(cap0, &codec_buf0), ast_format_cap_get_names(cap1, &codec_buf1)); return 0; } read_ptime0 = ast_format_cap_get_format_framing(cap0, ast_channel_rawreadformat(bc0->chan)); read_ptime1 = ast_format_cap_get_format_framing(cap1, ast_channel_rawreadformat(bc1->chan)); write_ptime0 = ast_format_cap_get_format_framing(cap0, ast_channel_rawwriteformat(bc0->chan)); write_ptime1 = ast_format_cap_get_format_framing(cap1, ast_channel_rawwriteformat(bc1->chan)); if (read_ptime0 != write_ptime1 || read_ptime1 != write_ptime0) { ast_debug(1, "Bridge '%s': Packetization differs between RTP streams (%d != %d or %d != %d). Cannot native bridge in RTP\n", bridge->uniqueid, read_ptime0, write_ptime1, read_ptime1, write_ptime0); return 0; } return 1; }