Bug 810220 - Patch to fix SDP Codec Negotiation Issues r=ekr,jesup

This commit is contained in:
Crypt 2012-11-26 02:36:43 -08:00
parent f24b3835b0
commit 760d7315ac
6 changed files with 277 additions and 95 deletions

View File

@ -82,3 +82,72 @@ vcm_media_payload_type_t vcmRtpToMediaPayload (int32_t ptype,
}
return type;
}
#define EXTRACT_DYNAMIC_PAYLOAD_TYPE(PTYPE) ((PTYPE)>>16)
#define CLEAR_DYNAMIC_PAYLOAD_TYPE(PTYPE) (PTYPE & 0x0000FFFF)
#define CHECK_DYNAMIC_PAYLOAD_TYPE(PTYPE) (PTYPE & 0xFFFF0000)
/* TODO -- This function is temporary, to deal with the fact
that we currently have two different codec representations.
It should be removed when the media types are unified. */
int32_t mediaPayloadToVcmRtp (vcm_media_payload_type_t payload_in)
{
int vcmPayload = -1;
int rtp_payload = -1;
if (CHECK_DYNAMIC_PAYLOAD_TYPE(payload_in)) {
vcmPayload = CLEAR_DYNAMIC_PAYLOAD_TYPE(payload_in);
} else {
//static payload type
vcmPayload = payload_in;
}
switch(vcmPayload) {
case VCM_Media_Payload_G711Ulaw64k:
rtp_payload = RTP_PCMU;
break;
case VCM_Media_Payload_G729:
rtp_payload = RTP_G729;
break;
case VCM_Media_Payload_Wide_Band_256k:
rtp_payload = RTP_L16;
break;
case VCM_Media_Payload_G722_64k:
rtp_payload = RTP_G722;
break;
case VCM_Media_Payload_ILBC20:
case VCM_Media_Payload_ILBC30:
rtp_payload = RTP_ILBC;
break;
case VCM_Media_Payload_ISAC:
rtp_payload = RTP_ISAC;
break;
case VCM_Media_Payload_H263:
rtp_payload = RTP_H263;
break;
case VCM_Media_Payload_H264:
rtp_payload = RTP_H264_P0;
break;
case VCM_Media_Payload_VP8:
rtp_payload = RTP_VP8;
break;
case VCM_Media_Payload_OPUS:
rtp_payload = RTP_OPUS;
break;
default:
rtp_payload = RTP_NONE;
break;
}
return rtp_payload;
}

View File

@ -24,6 +24,7 @@
#include "prlog.h"
#include "plstr.h"
#include "sdp_private.h"
#include "vcm_util.h"
//TODO Need to place this in a portable location
#define MULTICAST_START_ADDRESS 0xe1000000
@ -348,6 +349,8 @@ gsmsdp_free_media (fsmdef_media_t *media)
if(media->payloads != NULL) {
cpr_free(media->payloads);
cpr_free(media->local_dpt_list);
cpr_free(media->remote_dpt_list);
media->num_payloads = 0;
}
/*
@ -388,7 +391,6 @@ gsmsdp_init_media (fsmdef_media_t *media)
media->mode = (uint16_t)vcmGetILBCMode();
media->vad = VCM_VAD_OFF;
/* Default to audio codec */
media->payload = RTP_NONE;
media->level = 0;
media->dest_port = 0;
media->dest_addr = ip_addr_invalid;
@ -414,11 +416,14 @@ gsmsdp_init_media (fsmdef_media_t *media)
media->previous_sdp.direction = SDP_DIRECTION_INACTIVE;
media->previous_sdp.packetization_period = media->packetization_period;
media->previous_sdp.max_packetization_period = media->max_packetization_period;
media->previous_sdp.payload_type = media->payload;
media->previous_sdp.local_payload_type = media->payload;
media->previous_sdp.payload_type =
media->num_payloads ? media->payloads[0] : RTP_NONE;
media->previous_sdp.local_payload_type =
media->num_payloads ? media->payloads[0] : RTP_NONE;
media->previous_sdp.tias_bw = SDP_INVALID_VALUE;
media->previous_sdp.profile_level = 0;
media->local_dynamic_payload_type_value = media->payload;
media->local_dynamic_payload_type_value =
media->num_payloads ? media->payloads[0] : RTP_NONE;
media->hold = FSM_HOLD_NONE;
media->flags = 0; /* clear all flags */
media->cap_index = CC_MAX_MEDIA_CAP; /* max is invalid value */
@ -427,6 +432,8 @@ gsmsdp_init_media (fsmdef_media_t *media)
media->rtcp_mux = FALSE;
media->protocol = NULL;
media->payloads = NULL;
media->local_dpt_list = NULL;
media->remote_dpt_list = NULL;
media->num_payloads = 0;
}
@ -1661,7 +1668,7 @@ gsmsdp_set_local_sdp_direction (fsmdef_dcb_t *dcb_p,
if (media->direction_set) {
media->previous_sdp.direction = media->direction;
gsmsdp_remove_sdp_direction(media, media->direction,
dcb_p->sdp ? dcb_p->sdp->src_sdp: NULL );
dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL );
media->direction_set = FALSE;
}
gsmsdp_set_sdp_direction(media, direction, dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL);
@ -1926,18 +1933,30 @@ gsmsdp_add_default_audio_formats_to_local_sdp (fsmdef_dcb_t *dcb_p,
(rtp_ptype *) local_media_types,
CC_MAX_MEDIA_TYPES);
/*
* If the media payload type is set to RTP_NONE, its because we are making an
* If there are no media payload types, it's because we are making an
* initial offer. We will be opening our receive port so we need to specify
* the media payload type to be used initially. We set the media payload
* type in the dcb to do this. Until we receive an answer from the far
* end, we will use our first choice payload type. i.e. the first payload
* type sent in our AUDIO media line.
*/
if (dcb_p && media && media->payload == RTP_NONE) {
media->payload = local_media_types[0];
/* TODO -- Eventually, the structure in previous_sdp needs to be
updated to match the payloads[] array so that we can act on
a codec other than the first one changing. */
if (dcb_p && media && media->num_payloads == 0) {
if (!media->payloads) {
media->payloads = cpr_calloc(1, sizeof(vcm_media_payload_type_t));
media->local_dpt_list = cpr_calloc(1, sizeof(uint8_t));
media->remote_dpt_list = cpr_calloc(1, sizeof(uint8_t));
}
media->payloads[0] = local_media_types[0];
media->previous_sdp.payload_type = local_media_types[0];
media->previous_sdp.local_payload_type = local_media_types[0];
media->num_payloads = 1;
}
/* reset the local dynamic payload to NONE */
if (media) {
media->local_dynamic_payload_type_value = RTP_NONE;
@ -2061,10 +2080,22 @@ gsmsdp_add_default_video_formats_to_local_sdp (fsmdef_dcb_t *dcb_p,
* end, we will use our first choice payload type. i.e. the first payload
* type sent in our video media line.
*/
if (dcb_p && media && media->payload == RTP_NONE) {
media->payload = video_media_types[0];
/* TODO -- Eventually, the structure in previous_sdp needs to be
updated to match the payloads[] array so that we can act on
a codec other than the first one changing. */
if (dcb_p && media && media->num_payloads == 0) {
if (!media->payloads) {
media->payloads = (vcm_media_payload_type_t*)
cpr_calloc(1, sizeof(vcm_media_payload_type_t));
media->local_dpt_list = cpr_calloc(1, sizeof(uint8_t));
media->remote_dpt_list = cpr_calloc(1, sizeof(uint8_t));
}
media->payloads[0] = video_media_types[0];
media->previous_sdp.payload_type = video_media_types[0];
media->previous_sdp.local_payload_type = video_media_types[0];
media->num_payloads = 1;
}
/* reset the local dynamic payload to NONE */
if (media) {
@ -2241,6 +2272,7 @@ gsmsdp_update_local_sdp_media (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
uint16_t level;
void *sdp_p;
int sdpmode = 0;
int i = 0;
if (!dcb_p || !media) {
GSM_ERR_MSG(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname);
@ -2317,42 +2349,52 @@ gsmsdp_update_local_sdp_media (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
break;
}
} else {
/*
* add the single negotiated media format
* answer with the same dynamic payload type value, if a dynamic payload is choosen.
* Add negotiated codec list to the sdp
*/
if (media->remote_dynamic_payload_type_value > 0) {
dynamic_payload_type = media->remote_dynamic_payload_type_value;
} else {
dynamic_payload_type = media->payload;
}
result =
for(i=0; i < media->num_payloads; i++) {
// Get the PT value. If the remote party has
// specified a dynamic value for this payload,
// we re-use the same value they do. Otherwise,
// we use our own selected dynamic payload type.
if (media->remote_dpt_list[i] > 0) {
dynamic_payload_type = media->remote_dpt_list[i];
} else {
dynamic_payload_type = media->local_dpt_list[i];
}
result =
sdp_add_media_payload_type(sdp_p, level,
(uint16_t)dynamic_payload_type,
SDP_PAYLOAD_NUMERIC);
if (result != SDP_SUCCESS) {
if (result != SDP_SUCCESS) {
GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding dynamic payload type failed\n",
dcb_p->line, dcb_p->call_id, fname);
}
switch (media->type) {
case SDP_MEDIA_AUDIO:
gsmsdp_set_media_attributes(media->payload, sdp_p, level,
(uint16_t)dynamic_payload_type);
break;
case SDP_MEDIA_VIDEO:
gsmsdp_set_video_media_attributes(media->payload, cc_sdp_p, level,
(uint16_t)dynamic_payload_type);
break;
case SDP_MEDIA_APPLICATION:
gsmsdp_set_sctp_attributes (sdp_p, level, media);
break;
default:
GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR media %d for level %d is not"
" supported\n",
}
switch (media->type) {
case SDP_MEDIA_AUDIO:
gsmsdp_set_media_attributes(mediaPayloadToVcmRtp(
media->payloads[i]), sdp_p, level,
(uint16_t)dynamic_payload_type);
break;
case SDP_MEDIA_VIDEO:
gsmsdp_set_video_media_attributes(mediaPayloadToVcmRtp(
media->payloads[i]), cc_sdp_p, level,
(uint16_t)dynamic_payload_type);
break;
case SDP_MEDIA_APPLICATION:
gsmsdp_set_sctp_attributes (sdp_p, level, media);
break;
default:
GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR media %d for level %d is"
" not supported\n",
dcb_p->line, dcb_p->call_id, fname, media->level);
break;
}
break;
}
}//end for
/*
* add the avt media type
@ -2808,7 +2850,8 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
/*
* Save pay load type for use by gsmspd_compare_to_previous_sdp
*/
media->previous_sdp.payload_type = media->payload;
media->previous_sdp.payload_type =
media->num_payloads ? media->payloads[0] : RTP_NONE;
media->previous_sdp.local_payload_type = media->local_dynamic_payload_type_value;
/*
@ -2821,13 +2864,19 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
payload_types_count = num_slave_types;
}
media->payloads = (vcm_media_payload_type_t*) cpr_malloc(payload_types_count * sizeof(vcm_media_payload_type_t));
if (!(media->payloads))
{
GSM_ERR_MSG(GSM_L_C_F_PREFIX"Memory Allocation failed for payloads\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
return RTP_NONE;
/* Remove any previously allocated lists */
if (media->payloads) {
cpr_free(media->payloads);
cpr_free(media->local_dpt_list);
cpr_free(media->remote_dpt_list);
}
/* Allocate memory for PT value, local PT and remote PT. */
media->payloads = cpr_calloc(payload_types_count,
sizeof(vcm_media_payload_type_t));
media->local_dpt_list = cpr_calloc(payload_types_count,
sizeof(uint8_t));
media->remote_dpt_list = cpr_calloc(payload_types_count,
sizeof(uint8_t));
for (i = 0; i < num_master_types; i++) {
for (j = 0; j < num_slave_types; j++) {
@ -2842,7 +2891,7 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
}
} else { //if remote SDP is an answer
if (media->local_dynamic_payload_type_value == RTP_NONE ||
media->payload != media->previous_sdp.payload_type) {
!media->num_payloads || media->payloads[0] != media->previous_sdp.payload_type) {
/* If the the negotiated payload type is different from previous,
set it the local dynamic to payload type as this is what we offered*/
}
@ -2858,7 +2907,7 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
if (payload == RTP_ILBC) {
media->mode = (uint16_t)sdp_attr_get_fmtp_mode_for_payload_type
(sdp_p->dest_sdp, level, 0,
media->remote_dynamic_payload_type_value);
remote_dynamic_payload_type_value);
}
if (payload == RTP_OPUS) {
u16 a_inst;
@ -2908,14 +2957,13 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
vcmFreeMediaPtr(media->video);
media->video = NULL;
}
if ( vcmCheckAttribs(media->payload, sdp_p, level,
&media->video) == FALSE ) {
GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d ignored - attribs not accepted\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line,
dcb_p->call_id, fname), media->payload);
explicit_reject = TRUE;
continue; // keep looking
if ( vcmCheckAttribs(payload, sdp_p, level,
&media->video) == FALSE ) {
GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d ignored - attribs not accepted\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line,
dcb_p->call_id, fname), payload);
explicit_reject = TRUE;
continue; // keep looking
}
// cache the negotiated profile_level and bandwidth
@ -2929,7 +2977,7 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line,
dcb_p->call_id, fname), media->payload);
dcb_p->call_id, fname), payload);
}
found_codec = TRUE;
@ -2937,12 +2985,17 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
//we maxed our allocated memory. ignore and return;
return payload;
}
//update media structure with the negotiated value
media->payloads[media->num_payloads] = vcmRtpToMediaPayload(payload,
remote_dynamic_payload_type_value,
media->mode);
media->local_dpt_list[media->num_payloads] = payload;
media->remote_dpt_list[media->num_payloads] = remote_dynamic_payload_type_value;
media->num_payloads++;
if(offer) {
//return on the first match
// TODO -- Eventually, we'll (probably) want to answer with all
// the codecs we can receive. See bug 814227.
return payload;
}
}
@ -2962,20 +3015,20 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
*/
if (!initial_offer && explicit_reject == FALSE) {
for (i = 0; i < num_types; i++) {
if (media->payload == GET_CODEC_TYPE(remote_media_types[i])) {
if (media->num_payloads != 0 && media->payloads[0] == GET_CODEC_TYPE(remote_media_types[i])) {
/*
* CSCta40560 - DSP runs out of bandwidth as the current API's do not consider the request is for
* the same call. Need to update dynamic payload types for dynamic PT codecs. Would need to possibly
* add other video codecs as support is added here.
*/
if ( (media->payload == RTP_H264_P1 || media->payload == RTP_H264_P0) && offer == TRUE ) {
if ( (media->payloads[0] == RTP_H264_P1 || media->payloads[0] == RTP_H264_P0) && offer == TRUE ) {
media->remote_dynamic_payload_type_value = GET_DYN_PAYLOAD_TYPE_VALUE(master_list_p[i]);
media->local_dynamic_payload_type_value = GET_DYN_PAYLOAD_TYPE_VALUE(master_list_p[i]);
}
GSM_DEBUG(DEB_L_C_F_PREFIX"local codec list was empty codec= %d local=%d remote =%d\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname),
media->payload, media->local_dynamic_payload_type_value, media->remote_dynamic_payload_type_value);
return (media->payload);
media->payloads[0], media->local_dynamic_payload_type_value, media->remote_dynamic_payload_type_value);
return (media->payloads[0]);
}
}
}
@ -4141,7 +4194,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
GSM_DEBUG(DEB_L_C_F_PREFIX"remote_direction: %d global match %sfound\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname),
remote_direction, (cap_index != CC_MAX_MEDIA_CAP)?"":"not ");
remote_direction, (cap_index != CC_MAX_MEDIA_CAP) ? "" : "not ");
if ( cap_index != CC_MAX_MEDIA_CAP &&
remote_direction != SDP_DIRECTION_INACTIVE ) {
// this is an offer and platform can support video
@ -4756,11 +4809,17 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
* Since we are initiating an initial offer and opening a
* receive port, store initial media settings.
*/
/* TODO -- Eventually, the structure in previous_sdp needs to be
updated to match the payloads[] array so that we can act on
a codec other than the first one changing. */
media->previous_sdp.avt_payload_type = media->avt_payload_type;
media->previous_sdp.direction = media->direction;
media->previous_sdp.packetization_period = media->packetization_period;
media->previous_sdp.payload_type = media->payload;
media->previous_sdp.local_payload_type = media->payload;
media->previous_sdp.payload_type =
media->num_payloads ? media->payloads[0] : RTP_NONE;
media->previous_sdp.local_payload_type =
media->num_payloads ? media->payloads[0] : RTP_NONE;
break;
}
@ -6231,11 +6290,14 @@ gsmsdp_sdp_differs_from_previous_sdp (boolean rcv_only, fsmdef_media_t *media)
* Consider attributes of interest common to all active directions.
*/
if ((media->previous_sdp.avt_payload_type != media->avt_payload_type) ||
(media->previous_sdp.payload_type != media->payload)) {
(0 == media->num_payloads) ||
(media->previous_sdp.payload_type != media->payloads[0])) {
GSM_DEBUG(DEB_F_PREFIX"previous payload: %d new payload: %d\n",
DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.payload_type, media->payload);
DEB_F_PREFIX_ARGS(GSM, fname),
media->previous_sdp.payload_type, media->payloads[0]);
GSM_DEBUG(DEB_F_PREFIX"previous avt payload: %d new avt payload: %d\n",
DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.avt_payload_type,
DEB_F_PREFIX_ARGS(GSM, fname),
media->previous_sdp.avt_payload_type,
media->avt_payload_type);
return TRUE;
}

View File

@ -146,7 +146,6 @@ typedef struct fsmdef_media_t_ {
* We answer with the same payload type value that the remote offers.
* If remote choses to answer with different value than we offer, we support asymmetric.
*/
int32_t payload; //payload type - one of rtp_ptype enumerations
int32_t local_dynamic_payload_type_value; // dynamic payload type value offered/answered by us
int32_t remote_dynamic_payload_type_value; // dynamic payload type value offered/answered by remote
int32_t avt_payload_type;
@ -237,11 +236,30 @@ typedef struct fsmdef_media_t_ {
uint32 streams;
char *protocol;
/*
* This field contains the size of the payloads,
* local_dpt_list, and remote_dpt_list fields.
*/
int32_t num_payloads;
/*
* List of active lists of payloads negotiated
* There needs to be 1-1 mapping between the 3 arrays
* TODO:crypt: Move these to a aggregate structure per payload
* since we need to include codec type, local rtp type, remote rty type,
* codec specific parameters as generated by any SDP action.
*/
vcm_media_payload_type_t* payloads;
int32_t num_payloads;
/*
* dynamic payload type value offered/answered by us
*/
uint8_t* local_dpt_list;
/*
* dynamic payload type value offered/answered by remote
*/
uint8_t* remote_dpt_list;
} fsmdef_media_t;
struct fsm_fcb_t_;

View File

@ -995,7 +995,8 @@ lsm_rx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
pc_track_id = 0;
dcb->cur_video_avail &= ~CC_ATTRIB_CAST;
if (media->local_dynamic_payload_type_value == RTP_NONE) {
media->local_dynamic_payload_type_value = media->payload;
media->local_dynamic_payload_type_value =
media->num_payloads ? media->payloads[0] : RTP_NONE;
}
config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
@ -1014,9 +1015,15 @@ lsm_rx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
} else if (!sdpmode) {
ret_val = vcmRxStart(media->cap_index, group_id, media->refid,
lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID),
vcmRtpToMediaPayload(media->payload,
media->local_dynamic_payload_type_value,
media->mode),
/* RTP_NONE is not technically a valid
value for vcm_media_payload_type_t.
However, we really should never
reach this part of the code with
num_payloads < 1, so the RTP_NONE
shouldn't ever be used. It's only
here are extra protection against
an invalid pointer deref.*/
media->num_payloads ? media->payloads[0] : RTP_NONE,
media->is_multicast ? &media->dest_addr:&media->src_addr,
port,
FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media),
@ -1235,9 +1242,7 @@ lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
if (vcmTxStart(media->cap_index, group_id,
media->refid,
lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID),
vcmRtpToMediaPayload(media->payload,
media->remote_dynamic_payload_type_value,
media->mode),
media->num_payloads ? media->payloads[0] : RTP_NONE,
(short)dscp,
&media->src_addr,
media->src_port,
@ -1263,9 +1268,7 @@ lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
dcb->media_cap_tbl->cap[media->cap_index].pc_track,
lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID),
dcb->peerconnection,
vcmRtpToMediaPayload(media->payload,
media->remote_dynamic_payload_type_value,
media->mode),
media->num_payloads ? media->payloads[0] : RTP_NONE,
(short)dscp,
FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media),
FSM_NEGOTIATED_CRYPTO_DIGEST(media),
@ -1949,7 +1952,7 @@ lsm_get_free_lcb (callid_t call_id, line_t line, fsmdef_dcb_t *dcb)
lcb->mru = mru;
lcb->dcb = dcb;
// start unmuted if txPref is true
lcb->vid_mute = cc_media_getVideoAutoTxPref()?FALSE:TRUE;
lcb->vid_mute = cc_media_getVideoAutoTxPref() ? FALSE : TRUE;
lcb->ui_id = call_id; /* default UI ID is the same as call_id */
break;
@ -3857,12 +3860,16 @@ lsm_update_media (lsm_lcb_t *lcb, const char *caller_fname)
if (LSMDebug) {
/* debug is enabled, format the dest addr into string */
ipaddr2dotted(addr_str, &media->dest_addr);
for (int i = 0; i < media->num_payloads; i++)
{
LSM_DEBUG(DEB_L_C_F_PREFIX"%d rx, tx refresh's are %d %d"
", dir=%d, payload=%d addr=%s, multicast=%d\n",
DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line,
dcb->call_id, fname), media->refid, rx_refresh,
tx_refresh, media->direction,
media->payloads[i], addr_str, media->is_multicast );
}
}
LSM_DEBUG(DEB_L_C_F_PREFIX"%d rx, tx refresh's are %d %d"
", dir=%d, payload=%d addr=%s, multicast=%d\n",
DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname),
media->refid, rx_refresh, tx_refresh, media->direction,
media->payload, addr_str, media->is_multicast );
if (rx_refresh ||
(media->is_multicast &&
media->direction_set &&
@ -5289,9 +5296,9 @@ void lsm_add_remote_stream (line_t line, callid_t call_id, fsmdef_media_t *media
return;
}
vcmCreateRemoteStream(media->cap_index, dcb->peerconnection, pc_stream_id,
vcmRtpToMediaPayload(media->payload,
media->local_dynamic_payload_type_value,media->mode));
vcmCreateRemoteStream(media->cap_index, dcb->peerconnection,
pc_stream_id,
media->num_payloads ? media->payloads[0] : RTP_NONE);
}
}

View File

@ -19,4 +19,5 @@ vcm_media_payload_type_t vcm_rtp_to_media_payload (int32_t ptype,
uint16_t mode);
int32_t mediaPayloadToVcmRtp (vcm_media_payload_type_t payload_in);
#endif /* VCM_UTIL_H_ */

View File

@ -575,7 +575,8 @@ class SignalingAgent {
}
void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer,
uint32_t offerAnswerFlags, uint32_t sdpCheck) {
uint32_t offerAnswerFlags,
uint32_t sdpCheck = DONT_CHECK_AUDIO|DONT_CHECK_VIDEO) {
// Create a media stream as if it came from GUM
nsRefPtr<nsDOMMediaStream> domMediaStream = new nsDOMMediaStream();
@ -1217,7 +1218,8 @@ TEST_F(SignalingTest, FullCallTrickle)
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
}
TEST_F(SignalingTest, Bug810220)
// This test comes from Bug 810220
TEST_F(SignalingTest, AudioOnlyG711Call)
{
sipcc::MediaConstraints constraints;
std::string offer =
@ -1228,10 +1230,11 @@ TEST_F(SignalingTest, Bug810220)
"t=0 0\r\n"
"a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
"7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
"m=audio 9000 RTP/AVP 0 126\r\n"
"m=audio 9000 RTP/AVP 0 8 126\r\n"
"c=IN IP4 148.147.200.251\r\n"
"b=TIAS:64000\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:8 PCMA/8000\r\n"
"a=rtpmap:126 telephone-event/8000\r\n"
"a=candidate:0 1 udp 2130706432 148.147.200.251 9000 typ host\r\n"
"a=candidate:0 2 udp 2130706432 148.147.200.251 9005 typ host\r\n"
@ -1247,12 +1250,29 @@ TEST_F(SignalingTest, Bug810220)
DONT_CHECK_AUDIO | DONT_CHECK_VIDEO);
std::string answer = a2_.answer();
/* TODO -- make sure the answer looks right */
// They didn't offer opus, so our answer shouldn't include it.
ASSERT_EQ(answer.find(" opus/"), std::string::npos);
// They also didn't offer video or application
ASSERT_EQ(answer.find("video"), std::string::npos);
ASSERT_EQ(answer.find("application"), std::string::npos);
// We should answer with PCMU and telephone-event
ASSERT_NE(answer.find(" PCMU/8000"), std::string::npos);
ASSERT_NE(answer.find(" telephone-event/8000"), std::string::npos);
// Double-check the directionality
ASSERT_NE(answer.find("\r\na=sendrecv"), std::string::npos);
}
TEST_F(SignalingTest, Bug814038)
// This test comes from Bug814038
TEST_F(SignalingTest, ChromeOfferAnswer)
{
sipcc::MediaConstraints constraints;
// This is captured SDP from an early interop attempt with Chrome.
std::string offer =
"v=0\r\n"
"o=- 1713781661 2 IN IP4 127.0.0.1\r\n"
@ -1275,7 +1295,12 @@ TEST_F(SignalingTest, Bug814038)
"RzrYlzpkTsvgYFD1hQqNCzQ7y4emNLKI1tODsjim\r\n"
"a=rtpmap:103 ISAC/16000\r\n"
"a=rtpmap:104 ISAC/32000\r\n"
"a=rtpmap:111 opus/48000\r\n"
// NOTE: the actual SDP that Chrome sends at the moment
// doesn't indicate two channels. I've amended their SDP
// here, under the assumption that the constraints
// described in draft-spittka-payload-rtp-opus will
// eventually be implemented by Google.
"a=rtpmap:111 opus/48000/2\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:8 PCMA/8000\r\n"
"a=rtpmap:107 CN/48000\r\n"
@ -1314,13 +1339,13 @@ TEST_F(SignalingTest, Bug814038)
a2_.SetRemote(TestObserver::OFFER, offer);
std::cout << "Creating answer:" << std::endl;
a2_.CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO,
SHOULD_INACTIVE_AUDIO | SHOULD_INACTIVE_VIDEO);
a2_.CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
std::string answer = a2_.answer();
}
} // End namespace test.
int main(int argc, char **argv) {