예제 #1
0
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;
}
예제 #2
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, 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;
}