static int container_test3_helper(int nolocking, struct ast_test *test) { int x; int res = AST_TEST_PASS; struct ast_format_cap *cap1; struct ast_format_cap *cap2; struct ast_format_cap *joint; for (x = 0; x < 2000; x++) { if (nolocking) { cap1 = ast_format_cap_alloc_nolock(); cap2 = ast_format_cap_alloc_nolock(); joint = ast_format_cap_alloc_nolock(); } else { cap1 = ast_format_cap_alloc(); cap2 = ast_format_cap_alloc(); joint = ast_format_cap_alloc(); } if (!cap1 || !cap2 || !joint) { ast_test_status_update(test, "cap alloc fail\n"); return AST_TEST_FAIL; } ast_format_cap_add_all(cap1); ast_format_cap_add_all_by_type(cap2, AST_FORMAT_TYPE_AUDIO); ast_format_cap_joint_copy(cap1, cap2, joint); if (!(ast_format_cap_identical(cap2, joint))) { ast_test_status_update(test, "failed identical test\n"); res = AST_TEST_FAIL; cap1 = ast_format_cap_destroy(cap1); cap2 = ast_format_cap_destroy(cap2); joint = ast_format_cap_destroy(joint); break; } cap1 = ast_format_cap_destroy(cap1); cap2 = ast_format_cap_destroy(cap2); joint = ast_format_cap_destroy(joint); } return res; }
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, ast_format_cap_destroy); RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy); RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy); enum ast_format_type media_type = stream_to_media_type(session_media->stream_type); struct ast_rtp_codecs codecs; struct ast_format fmt; int fmts = 0; int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) && !ast_format_cap_is_empty(session->direct_media_cap); if (!(caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK)) || !(peer = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) { 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_joint_copy(session->endpoint->media.codecs, session->direct_media_cap, caps); } else { ast_format_cap_copy(caps, session->endpoint->media.codecs); } format_cap_only_type(caps, 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 */ if (!(joint = ast_format_cap_joint(caps, peer))) { char usbuf[64], thembuf[64]; ast_rtp_codecs_payloads_destroy(&codecs); ast_getformatname_multiple(usbuf, sizeof(usbuf), caps); ast_getformatname_multiple(thembuf, sizeof(thembuf), peer); ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf); return -1; } ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp), session_media->rtp); ast_format_cap_copy(caps, session->req_caps); ast_format_cap_remove_bytype(caps, media_type); ast_format_cap_append(caps, joint); ast_format_cap_append(session->req_caps, caps); if (session->channel) { ast_format_cap_copy(caps, ast_channel_nativeformats(session->channel)); ast_format_cap_remove_bytype(caps, media_type); ast_codec_choose(&session->endpoint->media.prefs, joint, 1, &fmt); ast_format_cap_add(caps, &fmt); /* Apply the new formats to the channel, potentially changing read/write formats while doing so */ ast_format_cap_copy(ast_channel_nativeformats(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_rtp_codecs_payloads_destroy(&codecs); return 0; }