Esempio n. 1
0
PJ_DEF(pj_status_t) pjmedia_codec_g7221_match_sdp(pj_pool_t *pool,
						  pjmedia_sdp_media *offer,
						  unsigned o_fmt_idx,
						  pjmedia_sdp_media *answer,
						  unsigned a_fmt_idx,
						  unsigned option)
{
    const pjmedia_sdp_attr *attr_ans;
    const pjmedia_sdp_attr *attr_ofr;
    pjmedia_sdp_fmtp fmtp;
    unsigned a_bitrate, o_bitrate;
    const pj_str_t bitrate = {"bitrate=", 8};
    pj_status_t status;

    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(option);

    /* Parse offer */
    attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", 
					    &offer->desc.fmt[o_fmt_idx]);
    if (!attr_ofr)
	return PJMEDIA_SDP_EINFMTP;

    status = pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp);
    if (status != PJ_SUCCESS)
	return status;

    GET_FMTP_IVAL(o_bitrate, fmtp, bitrate, 0);

    /* Parse answer */
    attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", 
					    &answer->desc.fmt[a_fmt_idx]);
    if (!attr_ans)
	return PJMEDIA_SDP_EINFMTP;

    status = pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp);
    if (status != PJ_SUCCESS)
	return status;

    GET_FMTP_IVAL(a_bitrate, fmtp, bitrate, 0);

    /* Compare bitrate in answer and offer. */
    if (a_bitrate != o_bitrate)
	return PJMEDIA_SDP_EFORMATNOTEQUAL;

    return PJ_SUCCESS;
}
Esempio n. 2
0
/* Matching G722.1 bitrates between offer and answer.
 */
static pj_bool_t match_g7221( const pjmedia_sdp_media *offer,
			      unsigned o_fmt_idx,
			      const pjmedia_sdp_media *answer,
			      unsigned a_fmt_idx)
{
    const pjmedia_sdp_attr *attr_ans;
    const pjmedia_sdp_attr *attr_ofr;
    pjmedia_sdp_fmtp fmtp;
    unsigned a_bitrate, o_bitrate;
    const pj_str_t bitrate = {"bitrate=", 8};

    /* Parse offer */
    attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", 
					    &offer->desc.fmt[o_fmt_idx]);
    if (!attr_ofr)
	return PJ_FALSE;

    if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS)
	return PJ_FALSE;

    GET_FMTP_IVAL(o_bitrate, fmtp, bitrate, 0);

    /* Parse answer */
    attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", 
					    &answer->desc.fmt[a_fmt_idx]);
    if (!attr_ans)
	return PJ_FALSE;

    if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS)
	return PJ_FALSE;

    GET_FMTP_IVAL(a_bitrate, fmtp, bitrate, 0);

    /* Compare bitrate in answer and offer. */
    return (a_bitrate == o_bitrate);
}
Esempio n. 3
0
/* Negotiate AMR format params between offer and answer. Format params
 * to be matched are: octet-align, crc, robust-sorting, interleaving, 
 * and channels (channels is negotiated by rtpmap line negotiation). 
 * Note: For answerer, octet-align mode setting is adaptable to offerer 
 *       setting. In the case that octet-align mode need to be adjusted,
 *       pt_need_adapt will be set to the format ID.
 *       
 */
static pj_bool_t match_amr( const pjmedia_sdp_media *offer,
			    unsigned o_fmt_idx,
			    const pjmedia_sdp_media *answer,
			    unsigned a_fmt_idx,
			    pj_bool_t answerer,
			    pj_str_t *pt_need_adapt)
{
    /* Negotiated format-param field-names constants. */
    const pj_str_t STR_OCTET_ALIGN	= {"octet-align=", 12};
    const pj_str_t STR_CRC		= {"crc=", 4};
    const pj_str_t STR_ROBUST_SORTING	= {"robust-sorting=", 15};
    const pj_str_t STR_INTERLEAVING	= {"interleaving=", 13};

    /* Negotiated params and their default values. */
    unsigned a_octet_align = 0, o_octet_align = 0;
    unsigned a_crc = 0, o_crc = 0;
    unsigned a_robust_sorting = 0, o_robust_sorting = 0;
    unsigned a_interleaving = 0, o_interleaving = 0;

    const pjmedia_sdp_attr *attr_ans;
    const pjmedia_sdp_attr *attr_ofr;
    pjmedia_sdp_fmtp fmtp;
    pj_bool_t match;

    /* Parse offerer FMTP */
    attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", 
					    &offer->desc.fmt[o_fmt_idx]);
    if (attr_ofr) {
	if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS)
	    /* Invalid fmtp format. */
	    return PJ_FALSE;

	GET_FMTP_IVAL(o_octet_align, fmtp, STR_OCTET_ALIGN, 0);
	GET_FMTP_IVAL(o_crc, fmtp, STR_CRC, 0);
	GET_FMTP_IVAL(o_robust_sorting, fmtp, STR_ROBUST_SORTING, 0);
	GET_FMTP_IVAL(o_interleaving, fmtp, STR_INTERLEAVING, 0);
    }

    /* Parse answerer FMTP */
    attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", 
					    &answer->desc.fmt[a_fmt_idx]);
    if (attr_ans) {
	if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS)
	    /* Invalid fmtp format. */
	    return PJ_FALSE;

	GET_FMTP_IVAL(a_octet_align, fmtp, STR_OCTET_ALIGN, 0);
	GET_FMTP_IVAL(a_crc, fmtp, STR_CRC, 0);
	GET_FMTP_IVAL(a_robust_sorting, fmtp, STR_ROBUST_SORTING, 0);
	GET_FMTP_IVAL(a_interleaving, fmtp, STR_INTERLEAVING, 0);
    }

    if (answerer) {
	match = a_crc == o_crc &&
		a_robust_sorting == o_robust_sorting &&
		a_interleaving == o_interleaving;

	/* If answerer octet-align setting doesn't match to the offerer's, 
	 * set pt_need_adapt to this media format ID to signal the caller
	 * that this format ID needs to be adjusted.
	 */
	if (a_octet_align != o_octet_align && match) {
	    pj_assert(pt_need_adapt != NULL);
	    *pt_need_adapt = answer->desc.fmt[a_fmt_idx];
	}
    } else {
	match = (a_octet_align == o_octet_align &&
		 a_crc == o_crc &&
		 a_robust_sorting == o_robust_sorting &&
		 a_interleaving == o_interleaving);
    }

    return match;
}
PJ_DEF(pj_status_t) pjmedia_codec_amr_match_sdp( pj_pool_t *pool,
						 pjmedia_sdp_media *offer,
						 unsigned o_fmt_idx,
						 pjmedia_sdp_media *answer,
						 unsigned a_fmt_idx,
						 unsigned option)
{
    /* Negotiated format-param field-names constants. */
    const pj_str_t STR_OCTET_ALIGN	= {"octet-align=", 12};
    const pj_str_t STR_CRC		= {"crc=", 4};
    const pj_str_t STR_ROBUST_SORTING	= {"robust-sorting=", 15};
    const pj_str_t STR_INTERLEAVING	= {"interleaving=", 13};

    /* Negotiated params and their default values. */
    unsigned a_octet_align = 0, o_octet_align = 0;
    unsigned a_crc = 0, o_crc = 0;
    unsigned a_robust_sorting = 0, o_robust_sorting = 0;
    unsigned a_interleaving = 0, o_interleaving = 0;

    const pjmedia_sdp_attr *attr_ans;
    const pjmedia_sdp_attr *attr_ofr;
    pjmedia_sdp_fmtp fmtp;
    pj_status_t status;

    /* Parse offerer FMTP */
    attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", 
					    &offer->desc.fmt[o_fmt_idx]);
    if (attr_ofr) {
	status = pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp);
	if (status != PJ_SUCCESS)
	    return status;

	GET_FMTP_IVAL(o_octet_align, fmtp, STR_OCTET_ALIGN, 0);
	GET_FMTP_IVAL(o_crc, fmtp, STR_CRC, 0);
	GET_FMTP_IVAL(o_robust_sorting, fmtp, STR_ROBUST_SORTING, 0);
	GET_FMTP_IVAL(o_interleaving, fmtp, STR_INTERLEAVING, 0);
    }

    /* Parse answerer FMTP */
    attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", 
					    &answer->desc.fmt[a_fmt_idx]);
    if (attr_ans) {
	status = pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp);
	if (status != PJ_SUCCESS)
	    return status;

	GET_FMTP_IVAL(a_octet_align, fmtp, STR_OCTET_ALIGN, 0);
	GET_FMTP_IVAL(a_crc, fmtp, STR_CRC, 0);
	GET_FMTP_IVAL(a_robust_sorting, fmtp, STR_ROBUST_SORTING, 0);
	GET_FMTP_IVAL(a_interleaving, fmtp, STR_INTERLEAVING, 0);
    }

    /* First, match crc, robust-sorting, interleaving settings */
    if (a_crc != o_crc ||
	a_robust_sorting != o_robust_sorting ||
	a_interleaving != o_interleaving)
    {
	return PJMEDIA_SDP_EFORMATNOTEQUAL;
    }

    /* Match octet-align setting */
    if (a_octet_align != o_octet_align) {
	/* Check if answer can be modified to match to the offer */
	if (option & PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER) {
	    status = amr_toggle_octet_align(pool, answer, a_fmt_idx);
	    return status;
	} else {
	    return PJMEDIA_SDP_EFORMATNOTEQUAL;
	}
    }

    return PJ_SUCCESS;
}