зеркало из https://github.com/mozilla/gecko-dev.git
Bug 880067 - Part 1: SDP rtcp-fb parsing/serializing r=ekr,ehugg
This commit is contained in:
Родитель
2963da8a16
Коммит
9e693b0903
|
@ -1642,6 +1642,146 @@ gsmsdp_set_ice_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, char
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_rtcp_fb_ack_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds an rtcp-fb:...ack attribute attributes to the specified SDP.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* level - The media level of the SDP where the media attribute exists.
|
||||
* sdp_p - Pointer to the SDP to set the ice candidate attribute against.
|
||||
* ack_type - Type of ack feedback mechanism in use
|
||||
*/
|
||||
void
|
||||
gsmsdp_set_rtcp_fb_ack_attribute (uint16_t level,
|
||||
void *sdp_p,
|
||||
u16 payload_type,
|
||||
sdp_rtcp_fb_ack_type_e ack_type)
|
||||
{
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_rtcp_fb_ack(sdp_p, level, payload_type,
|
||||
a_instance, ack_type);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_rtcp_fb_nack_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds an rtcp-fb:...nack attribute attributes to the specified SDP.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* level - The media level of the SDP where the media attribute exists.
|
||||
* sdp_p - Pointer to the SDP to set the ice candidate attribute against.
|
||||
* nack_type - Type of nack feedback mechanism in use
|
||||
*/
|
||||
void
|
||||
gsmsdp_set_rtcp_fb_nack_attribute (uint16_t level,
|
||||
void *sdp_p,
|
||||
u16 payload_type,
|
||||
sdp_rtcp_fb_nack_type_e nack_type)
|
||||
{
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_rtcp_fb_nack(sdp_p, level, payload_type,
|
||||
a_instance, nack_type);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_rtcp_fb_trr_int_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds an rtcp-fb:...trr-int attribute attributes to the specified SDP.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* level - The media level of the SDP where the media attribute exists.
|
||||
* sdp_p - Pointer to the SDP to set the ice candidate attribute against.
|
||||
* trr_interval - Interval to set trr-int value to
|
||||
*/
|
||||
void
|
||||
gsmsdp_set_rtcp_fb_trr_int_attribute (uint16_t level,
|
||||
void *sdp_p,
|
||||
u16 payload_type,
|
||||
u32 trr_interval)
|
||||
{
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_rtcp_fb_trr_int(sdp_p, level, payload_type,
|
||||
a_instance, trr_interval);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_rtcp_fb_ccm_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds an rtcp-fb:...ccm attribute attributes to the specified SDP.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* level - The media level of the SDP where the media attribute exists.
|
||||
* sdp_p - Pointer to the SDP to set the ice candidate attribute against.
|
||||
* ccm_type - Type of ccm feedback mechanism in use
|
||||
*/
|
||||
void
|
||||
gsmsdp_set_rtcp_fb_ccm_attribute (uint16_t level,
|
||||
void *sdp_p,
|
||||
u16 payload_type,
|
||||
sdp_rtcp_fb_ccm_type_e ccm_type)
|
||||
{
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_rtcp_fb_ccm(sdp_p, level, payload_type,
|
||||
a_instance, ccm_type);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_rtcp_mux_attribute
|
||||
*
|
||||
|
@ -4666,6 +4806,19 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
|
|||
break;
|
||||
}
|
||||
|
||||
/* TODO (abr) -- temporarily hardcode rtcb-fb attributes to match our
|
||||
actual behavior. This really needs to be a negotiation, with the
|
||||
results of the negotiation propagating into the codec configuration.
|
||||
See Bug 880067. */
|
||||
if (media_type == SDP_MEDIA_VIDEO) {
|
||||
gsmsdp_set_rtcp_fb_nack_attribute(media->level, sdp_p->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
gsmsdp_set_rtcp_fb_ccm_attribute(media->level, sdp_p->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_CCM_FIR);
|
||||
}
|
||||
|
||||
if (unsupported_line) {
|
||||
/* add this line to unsupported line */
|
||||
gsmsdp_add_unsupported_stream_to_local_sdp(sdp_p, i);
|
||||
|
@ -5230,6 +5383,20 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
|
|||
level = level - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO (abr) -- temporarily hardcode rtcb-fb attributes to match
|
||||
our actual behavior. This really needs to be a negotiation, with
|
||||
the results of the negotiation propagating into the codec
|
||||
configuration. See Bug 880067. */
|
||||
if (media_cap->type == SDP_MEDIA_VIDEO) {
|
||||
gsmsdp_set_rtcp_fb_nack_attribute(level, dcb_p->sdp->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
gsmsdp_set_rtcp_fb_ccm_attribute(level, dcb_p->sdp->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_CCM_FIR);
|
||||
}
|
||||
|
||||
}
|
||||
/* next capability */
|
||||
media_cap++;
|
||||
|
|
|
@ -474,6 +474,51 @@ typedef enum {
|
|||
SDP_RTCP_UNICAST_MODE_NOT_PRESENT
|
||||
} sdp_rtcp_unicast_mode_e;
|
||||
|
||||
/* a=rtcp-fb enumerations */
|
||||
|
||||
typedef enum {
|
||||
SDP_RTCP_FB_ANY = -1,
|
||||
SDP_RTCP_FB_ACK = 0,
|
||||
SDP_RTCP_FB_CCM,
|
||||
SDP_RTCP_FB_NACK,
|
||||
SDP_RTCP_FB_TRR_INT,
|
||||
SDP_MAX_RTCP_FB,
|
||||
SDP_RTCP_FB_UNKNOWN
|
||||
} sdp_rtcp_fb_type_e;
|
||||
|
||||
typedef enum {
|
||||
SDP_RTCP_FB_NACK_NOT_FOUND = -1,
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED = 0,
|
||||
SDP_RTCP_FB_NACK_SLI,
|
||||
SDP_RTCP_FB_NACK_PLI,
|
||||
SDP_RTCP_FB_NACK_RPSI,
|
||||
SDP_RTCP_FB_NACK_APP,
|
||||
SDP_RTCP_FB_NACK_RAI,
|
||||
SDP_RTCP_FB_NACK_TLLEI,
|
||||
SDP_RTCP_FB_NACK_PSLEI,
|
||||
SDP_RTCP_FB_NACK_ECN,
|
||||
SDP_MAX_RTCP_FB_NACK,
|
||||
SDP_RTCP_FB_NACK_UNKNOWN
|
||||
} sdp_rtcp_fb_nack_type_e;
|
||||
|
||||
typedef enum {
|
||||
SDP_RTCP_FB_ACK_NOT_FOUND = -1,
|
||||
SDP_RTCP_FB_ACK_RPSI = 0,
|
||||
SDP_RTCP_FB_ACK_APP,
|
||||
SDP_MAX_RTCP_FB_ACK,
|
||||
SDP_RTCP_FB_ACK_UNKNOWN
|
||||
} sdp_rtcp_fb_ack_type_e;
|
||||
|
||||
typedef enum {
|
||||
SDP_RTCP_FB_CCM_NOT_FOUND = -1,
|
||||
SDP_RTCP_FB_CCM_FIR = 0,
|
||||
SDP_RTCP_FB_CCM_TMMBR,
|
||||
SDP_RTCP_FB_CCM_TSTR,
|
||||
SDP_RTCP_FB_CCM_VBCM,
|
||||
SDP_MAX_RTCP_FB_CCM,
|
||||
SDP_RTCP_FB_CCM_UNKNOWN
|
||||
} sdp_rtcp_fb_ccm_type_e;
|
||||
|
||||
/*
|
||||
* sdp_srtp_fec_order_t
|
||||
* This type defines the order in which to perform FEC
|
||||
|
@ -827,6 +872,25 @@ typedef struct sdp_source_filter {
|
|||
char src_list[SDP_MAX_SRC_ADDR_LIST+1][SDP_MAX_STRING_LEN+1];
|
||||
} sdp_source_filter_t;
|
||||
|
||||
/*
|
||||
* a=rtcp-fb:<payload-type> <feedback-type> [<feedback-parameters>]
|
||||
* Defines RTCP feedback parameters
|
||||
*/
|
||||
#define SDP_ALL_PAYLOADS 0xFFFF
|
||||
typedef struct sdp_fmtp_fb {
|
||||
u16 payload_num; /* can be SDP_ALL_PAYLOADS */
|
||||
sdp_rtcp_fb_type_e feedback_type;
|
||||
union {
|
||||
sdp_rtcp_fb_ack_type_e ack;
|
||||
sdp_rtcp_fb_ccm_type_e ccm;
|
||||
sdp_rtcp_fb_nack_type_e nack;
|
||||
u32 trr_int;
|
||||
} param;
|
||||
char extra[SDP_MAX_STRING_LEN + 1]; /* Holds any trailing information that
|
||||
cannot be represented by preceding
|
||||
fields. */
|
||||
} sdp_fmtp_fb_t;
|
||||
|
||||
/*
|
||||
* b=<bw-modifier>:<val>
|
||||
*
|
||||
|
@ -939,12 +1003,13 @@ typedef struct sdp_attr {
|
|||
sdp_silencesupp_t silencesupp;
|
||||
sdp_mca_t *cap_p; /* A X-CAP or CDSC attribute */
|
||||
sdp_rtr_t rtr;
|
||||
sdp_comediadir_t comediadir;
|
||||
sdp_srtp_crypto_context_t srtp_context;
|
||||
sdp_comediadir_t comediadir;
|
||||
sdp_srtp_crypto_context_t srtp_context;
|
||||
sdp_mptime_t mptime;
|
||||
sdp_stream_data_t stream_data;
|
||||
char unknown[SDP_MAX_STRING_LEN+1];
|
||||
sdp_source_filter_t source_filter;
|
||||
sdp_fmtp_fb_t rtcp_fb;
|
||||
} attr;
|
||||
struct sdp_attr *next_p;
|
||||
} sdp_attr_t;
|
||||
|
@ -1028,7 +1093,6 @@ typedef struct {
|
|||
sdp_result_e (*build_func)(sdp_t *sdp_p, u16 level, flex_string *fs);
|
||||
} sdp_tokenarray_t;
|
||||
|
||||
|
||||
/* Attribute processing table. */
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
@ -2008,4 +2072,33 @@ sdp_result_e
|
|||
sdp_attr_set_dtls_fingerprint_attribute(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const char *dtls_fingerprint);
|
||||
|
||||
sdp_rtcp_fb_ack_type_e
|
||||
sdp_attr_get_rtcp_fb_ack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst);
|
||||
|
||||
sdp_rtcp_fb_nack_type_e
|
||||
sdp_attr_get_rtcp_fb_nack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst);
|
||||
|
||||
u32
|
||||
sdp_attr_get_rtcp_fb_trr_int(void *sdp_ptr, u16 level, u16 payload_type,
|
||||
u16 inst);
|
||||
|
||||
sdp_rtcp_fb_ccm_type_e
|
||||
sdp_attr_get_rtcp_fb_ccm(void *sdp_ptr, u16 level, u16 payload_type, u16 inst);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_ack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
sdp_rtcp_fb_ack_type_e type);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_nack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
sdp_rtcp_fb_nack_type_e);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_trr_int(void *sdp_ptr, u16 level, u16 payload_type,
|
||||
u16 inst, u32 interval);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_ccm(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
sdp_rtcp_fb_ccm_type_e);
|
||||
|
||||
#endif /* _SDP_H_ */
|
||||
|
|
|
@ -4755,3 +4755,242 @@ sdp_result_e sdp_parse_attr_rtcp_mux_attr (sdp_t *sdp_p, sdp_attr_t *attr_p, con
|
|||
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
sdp_result_e sdp_build_attr_rtcp_fb(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs)
|
||||
{
|
||||
flex_string_sprintf(fs, "a=%s:", sdp_attr[attr_p->type].name);
|
||||
|
||||
/* Payload Type */
|
||||
if (attr_p->attr.rtcp_fb.payload_num == SDP_ALL_PAYLOADS) {
|
||||
flex_string_sprintf(fs, "* ");
|
||||
} else {
|
||||
flex_string_sprintf(fs, "%d ",attr_p->attr.rtcp_fb.payload_num);
|
||||
}
|
||||
|
||||
/* Feedback Type */
|
||||
if (attr_p->attr.rtcp_fb.feedback_type < SDP_RTCP_FB_UNKNOWN) {
|
||||
flex_string_sprintf(fs, "%s",
|
||||
sdp_rtcp_fb_type_val[attr_p->attr.rtcp_fb.feedback_type].name);
|
||||
}
|
||||
|
||||
/* Feedback Type Parameters */
|
||||
switch (attr_p->attr.rtcp_fb.feedback_type) {
|
||||
case SDP_RTCP_FB_ACK:
|
||||
if (attr_p->attr.rtcp_fb.param.ack < SDP_MAX_RTCP_FB_ACK) {
|
||||
flex_string_sprintf(fs, " %s",
|
||||
sdp_rtcp_fb_ack_type_val[attr_p->attr.rtcp_fb.param.ack]
|
||||
.name);
|
||||
}
|
||||
break;
|
||||
case SDP_RTCP_FB_CCM: /* RFC 5104 */
|
||||
if (attr_p->attr.rtcp_fb.param.ccm < SDP_MAX_RTCP_FB_CCM) {
|
||||
flex_string_sprintf(fs, " %s",
|
||||
sdp_rtcp_fb_ccm_type_val[attr_p->attr.rtcp_fb.param.ccm]
|
||||
.name);
|
||||
}
|
||||
break;
|
||||
case SDP_RTCP_FB_NACK:
|
||||
if (attr_p->attr.rtcp_fb.param.nack > SDP_RTCP_FB_NACK_UNSPECIFIED
|
||||
&& attr_p->attr.rtcp_fb.param.nack < SDP_MAX_RTCP_FB_NACK) {
|
||||
flex_string_sprintf(fs, " %s",
|
||||
sdp_rtcp_fb_nack_type_val[attr_p->attr.rtcp_fb.param.nack]
|
||||
.name);
|
||||
}
|
||||
break;
|
||||
case SDP_RTCP_FB_TRR_INT:
|
||||
flex_string_sprintf(fs, " %u", attr_p->attr.rtcp_fb.param.trr_int);
|
||||
break;
|
||||
|
||||
case SDP_RTCP_FB_UNKNOWN:
|
||||
/* Contents are in the "extra" field */
|
||||
break;
|
||||
|
||||
default:
|
||||
CSFLogError(logTag, "%s Error: Invalid rtcp-fb enum (%d)",
|
||||
sdp_p->debug_str, attr_p->attr.rtcp_fb.feedback_type);
|
||||
return SDP_FAILURE;
|
||||
}
|
||||
|
||||
/* Tack on any information that cannot otherwise be represented by
|
||||
* the sdp_fmtp_fb_t structure. */
|
||||
if (attr_p->attr.rtcp_fb.extra[0]) {
|
||||
flex_string_sprintf(fs, " %s", attr_p->attr.rtcp_fb.extra);
|
||||
}
|
||||
|
||||
/* Line ending */
|
||||
flex_string_sprintf(fs, "\r\n");
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
static int find_token_enum(const char *attr_name,
|
||||
sdp_t *sdp_p,
|
||||
const char **ptr,
|
||||
const sdp_namearray_t *types,
|
||||
int type_count,
|
||||
int unknown_value)
|
||||
{
|
||||
sdp_result_e result = SDP_SUCCESS;
|
||||
char tmp[SDP_MAX_STRING_LEN+1];
|
||||
int i;
|
||||
|
||||
*ptr = sdp_getnextstrtok(*ptr, tmp, sizeof(tmp), " \t", &result);
|
||||
if (result != SDP_SUCCESS) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: problem parsing %s", sdp_p->debug_str, attr_name);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i < type_count; i++) {
|
||||
if (!cpr_strncasecmp(tmp, types[i].name, types[i].strlen)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return unknown_value;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_parse_attr_rtcp_fb (sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr)
|
||||
{
|
||||
sdp_result_e result = SDP_SUCCESS;
|
||||
sdp_fmtp_fb_t *rtcp_fb_p = &(attr_p->attr.rtcp_fb);
|
||||
char tmp[SDP_MAX_STRING_LEN+1];
|
||||
int i;
|
||||
|
||||
/* Set up attribute fields */
|
||||
rtcp_fb_p->payload_num = 0;
|
||||
rtcp_fb_p->feedback_type = SDP_RTCP_FB_UNKNOWN;
|
||||
rtcp_fb_p->extra[0] = '\0';
|
||||
|
||||
/* Skip WS (just in case) */
|
||||
while (*ptr == ' ' || *ptr == '\t') {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* Look for the special "*" payload type */
|
||||
if (*ptr == '*') {
|
||||
rtcp_fb_p->payload_num = SDP_ALL_PAYLOADS;
|
||||
ptr++;
|
||||
} else {
|
||||
/* If the pt is not '*', parse it out as an integer */
|
||||
rtcp_fb_p->payload_num = (u16)sdp_getnextnumtok(ptr, &ptr,
|
||||
" \t", &result);
|
||||
if (result != SDP_SUCCESS) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse payload type for rtcp-fb attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read feedback type */
|
||||
i = find_token_enum("rtcp-fb attribute", sdp_p, &ptr, sdp_rtcp_fb_type_val,
|
||||
SDP_MAX_RTCP_FB, SDP_RTCP_FB_UNKNOWN);
|
||||
if (i < 0) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse feedback type for rtcp-fb attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
rtcp_fb_p->feedback_type = (sdp_rtcp_fb_type_e) i;
|
||||
|
||||
switch(rtcp_fb_p->feedback_type) {
|
||||
case SDP_RTCP_FB_ACK:
|
||||
i = find_token_enum("rtcp-fb ack type", sdp_p, &ptr,
|
||||
sdp_rtcp_fb_ack_type_val,
|
||||
SDP_MAX_RTCP_FB_ACK, SDP_RTCP_FB_ACK_UNKNOWN);
|
||||
if (i < 0) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse ack type for rtcp-fb attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
rtcp_fb_p->param.ack = (sdp_rtcp_fb_ack_type_e) i;
|
||||
break;
|
||||
|
||||
case SDP_RTCP_FB_CCM:
|
||||
i = find_token_enum("rtcp-fb ccm type", sdp_p, &ptr,
|
||||
sdp_rtcp_fb_ccm_type_val,
|
||||
SDP_MAX_RTCP_FB_CCM, SDP_RTCP_FB_CCM_UNKNOWN);
|
||||
if (i < 0) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse ccm type for rtcp-fb attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
rtcp_fb_p->param.ccm = (sdp_rtcp_fb_ccm_type_e) i;
|
||||
|
||||
/* TODO -- We don't currently parse tmmbr parameters or vbcm
|
||||
submessage types. If we decide to support these modes of
|
||||
operation, we probably want to add parsing code for them.
|
||||
For the time being, they'll just end up parsed into "extra". */
|
||||
break;
|
||||
|
||||
case SDP_RTCP_FB_NACK:
|
||||
/* Skip any remaining WS -- see
|
||||
http://code.google.com/p/webrtc/issues/detail?id=1922 */
|
||||
while (*ptr == ' ' || *ptr == '\t') {
|
||||
ptr++;
|
||||
}
|
||||
/* Check for empty string */
|
||||
if (*ptr == '\r') {
|
||||
rtcp_fb_p->param.nack = SDP_RTCP_FB_NACK_UNSPECIFIED;
|
||||
break;
|
||||
}
|
||||
i = find_token_enum("rtcp-fb nack type", sdp_p, &ptr,
|
||||
sdp_rtcp_fb_nack_type_val,
|
||||
SDP_MAX_RTCP_FB_NACK, SDP_RTCP_FB_NACK_UNKNOWN);
|
||||
if (i < 0) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse nack type for rtcp-fb attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
rtcp_fb_p->param.nack = (sdp_rtcp_fb_nack_type_e) i;
|
||||
break;
|
||||
|
||||
case SDP_RTCP_FB_TRR_INT:
|
||||
rtcp_fb_p->param.trr_int = sdp_getnextnumtok(ptr, &ptr,
|
||||
" \t", &result);
|
||||
if (result != SDP_SUCCESS) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse trr-int value for rtcp-fb "
|
||||
"attribute", sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDP_RTCP_FB_UNKNOWN:
|
||||
/* Handled by "extra", below */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* This is an internal error, not a parsing error */
|
||||
CSFLogError(logTag, "%s Error: Invalid rtcp-fb enum (%d)",
|
||||
sdp_p->debug_str, attr_p->attr.rtcp_fb.feedback_type);
|
||||
return SDP_FAILURE;
|
||||
}
|
||||
|
||||
/* Skip any remaining WS */
|
||||
while (*ptr == ' ' || *ptr == '\t') {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* Just store the rest of the line in "extra" -- this will return
|
||||
a failure result if there is no more text, but that's fine. */
|
||||
ptr = sdp_getnextstrtok(ptr, rtcp_fb_p->extra,
|
||||
sizeof(rtcp_fb_p->extra), "\r\n", &result);
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -11872,3 +11872,333 @@ sdp_attr_set_sdescriptions_salt_size (void *sdp_ptr,
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* Function: sdp_find_rtcp_fb_attr
|
||||
* Description: Helper to find the nth instance of a rtcp-fb attribute of
|
||||
* the specified feedback type.
|
||||
* Parameters: sdp_p The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* payload_type The payload to get the attribute for
|
||||
* fb_type The feedback type to look for.
|
||||
* inst_num The attribute instance number to check.
|
||||
* Returns: Pointer to the attribute, or NULL if not found.
|
||||
*/
|
||||
|
||||
sdp_attr_t *
|
||||
sdp_find_rtcp_fb_attr (sdp_t *sdp_p,
|
||||
u16 level,
|
||||
u16 payload_type,
|
||||
sdp_rtcp_fb_type_e fb_type,
|
||||
u16 inst_num)
|
||||
{
|
||||
u16 attr_count=0;
|
||||
sdp_mca_t *mca_p;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
mca_p = sdp_find_media_level(sdp_p, level);
|
||||
if (!mca_p) {
|
||||
return (NULL);
|
||||
}
|
||||
for (attr_p = mca_p->media_attrs_p; attr_p; attr_p = attr_p->next_p) {
|
||||
if (attr_p->type == SDP_ATTR_RTCP_FB &&
|
||||
(attr_p->attr.rtcp_fb.payload_num == payload_type ||
|
||||
attr_p->attr.rtcp_fb.payload_num == SDP_ALL_PAYLOADS) &&
|
||||
attr_p->attr.rtcp_fb.feedback_type == fb_type) {
|
||||
attr_count++;
|
||||
if (attr_count == inst_num) {
|
||||
return (attr_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_rtcp_fb_ack
|
||||
* Description: Returns the value of the rtcp-fb:...ack attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* payload_type The payload to get the attribute for
|
||||
* inst_num The attribute instance number to check.
|
||||
* Returns: ACK type (SDP_RTCP_FB_ACK_NOT_FOUND if not present)
|
||||
*/
|
||||
sdp_rtcp_fb_ack_type_e
|
||||
sdp_attr_get_rtcp_fb_ack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_RTCP_FB_ACK_NOT_FOUND;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
|
||||
SDP_RTCP_FB_ACK, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
payload_type, inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_RTCP_FB_ACK_NOT_FOUND;
|
||||
}
|
||||
return (attr_p->attr.rtcp_fb.param.ack);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_rtcp_fb_nack
|
||||
* Description: Returns the value of the rtcp-fb:...nack attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* payload_type The payload to get the attribute for
|
||||
* inst_num The attribute instance number to check.
|
||||
* Returns: NACK type (SDP_RTCP_FB_NACK_NOT_FOUND if not present)
|
||||
*/
|
||||
sdp_rtcp_fb_nack_type_e
|
||||
sdp_attr_get_rtcp_fb_nack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_RTCP_FB_NACK_NOT_FOUND;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
|
||||
SDP_RTCP_FB_NACK, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
payload_type, inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_RTCP_FB_NACK_NOT_FOUND;
|
||||
}
|
||||
return (attr_p->attr.rtcp_fb.param.nack);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_rtcp_fb_trr_int
|
||||
* Description: Returns the value of the rtcp-fb:...trr-int attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* payload_type The payload to get the attribute for
|
||||
* inst_num The attribute instance number to check.
|
||||
* Returns: trr-int interval (0xFFFFFFFF if not found)
|
||||
*/
|
||||
u32
|
||||
sdp_attr_get_rtcp_fb_trr_int(void *sdp_ptr, u16 level,
|
||||
u16 payload_type, u16 inst)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
|
||||
SDP_RTCP_FB_TRR_INT, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
payload_type, inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
return (attr_p->attr.rtcp_fb.param.trr_int);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_rtcp_fb_ccm
|
||||
* Description: Returns the value of the rtcp-fb:...ccm attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* payload_type The payload to get the attribute for
|
||||
* inst_num The attribute instance number to check.
|
||||
* Returns: CCM type (SDP_RTCP_FB_CCM_NOT_FOUND if not present)
|
||||
*/
|
||||
sdp_rtcp_fb_ccm_type_e
|
||||
sdp_attr_get_rtcp_fb_ccm(void *sdp_ptr, u16 level, u16 payload_type, u16 inst)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_RTCP_FB_CCM_NOT_FOUND;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_rtcp_fb_attr(sdp_p, level, payload_type,
|
||||
SDP_RTCP_FB_CCM, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp-fb attribute, level %u, pt %u, "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
payload_type, inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_RTCP_FB_CCM_NOT_FOUND;
|
||||
}
|
||||
return (attr_p->attr.rtcp_fb.param.ccm);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_set_rtcp_fb_ack
|
||||
* Description: Sets the value of an rtcp-fb:...ack attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to set the attribute.
|
||||
* payload_type The value to set the payload type to for
|
||||
* this attribute. Can be SDP_ALL_PAYLOADS.
|
||||
* inst_num The attribute instance number to check.
|
||||
* type The ack type to indicate
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_ack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
sdp_rtcp_fb_ack_type_e type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return (SDP_INVALID_SDP_PTR);
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp_fb ack attribute, level %u "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
attr_p->attr.rtcp_fb.payload_num = payload_type;
|
||||
attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_ACK;
|
||||
attr_p->attr.rtcp_fb.param.ack = type;
|
||||
attr_p->attr.rtcp_fb.extra[0] = '\0';
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* Function: sdp_attr_set_rtcp_fb_nack
|
||||
* Description: Sets the value of an rtcp-fb:...nack attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to set the attribute.
|
||||
* payload_type The value to set the payload type to for
|
||||
* this attribute. Can be SDP_ALL_PAYLOADS.
|
||||
* inst_num The attribute instance number to check.
|
||||
* type The nack type to indicate
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_nack(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
sdp_rtcp_fb_nack_type_e type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return (SDP_INVALID_SDP_PTR);
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp_fb nack attribute, level %u "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
attr_p->attr.rtcp_fb.payload_num = payload_type;
|
||||
attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_NACK;
|
||||
attr_p->attr.rtcp_fb.param.nack = type;
|
||||
attr_p->attr.rtcp_fb.extra[0] = '\0';
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_set_rtcp_fb_trr_int
|
||||
* Description: Sets the value of an rtcp-fb:...trr-int attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to set the attribute.
|
||||
* payload_type The value to set the payload type to for
|
||||
* this attribute. Can be SDP_ALL_PAYLOADS.
|
||||
* inst_num The attribute instance number to check.
|
||||
* interval The interval time to indicate
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_trr_int(void *sdp_ptr, u16 level, u16 payload_type,
|
||||
u16 inst, u32 interval)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return (SDP_INVALID_SDP_PTR);
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp_fb trr-int attribute, level %u "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
attr_p->attr.rtcp_fb.payload_num = payload_type;
|
||||
attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_TRR_INT;
|
||||
attr_p->attr.rtcp_fb.param.trr_int = interval;
|
||||
attr_p->attr.rtcp_fb.extra[0] = '\0';
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_set_rtcp_fb_ccm
|
||||
* Description: Sets the value of an rtcp-fb:...ccm attribute
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to set the attribute.
|
||||
* payload_type The value to set the payload type to for
|
||||
* this attribute. Can be SDP_ALL_PAYLOADS.
|
||||
* inst_num The attribute instance number to check.
|
||||
* type The ccm type to indicate
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_rtcp_fb_ccm(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
sdp_rtcp_fb_ccm_type_e type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return (SDP_INVALID_SDP_PTR);
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s rtcp_fb ccm attribute, level %u "
|
||||
"instance %u not found.", sdp_p->debug_str, level,
|
||||
inst);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
attr_p->attr.rtcp_fb.payload_num = payload_type;
|
||||
attr_p->attr.rtcp_fb.feedback_type = SDP_RTCP_FB_CCM;
|
||||
attr_p->attr.rtcp_fb.param.ccm = type;
|
||||
attr_p->attr.rtcp_fb.extra[0] = '\0';
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -167,7 +167,9 @@ const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] =
|
|||
{"fingerprint", sizeof("fingerprint"),
|
||||
sdp_parse_attr_fingerprint_attr, sdp_build_attr_simple_string},
|
||||
{"maxptime", sizeof("maxptime"),
|
||||
sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32}
|
||||
sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
|
||||
{"rtcp-fb", sizeof("rtcp-fb"),
|
||||
sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb}
|
||||
};
|
||||
|
||||
/* Note: These *must* be in the same order as the enum types. */
|
||||
|
@ -441,6 +443,47 @@ const sdp_namearray_t sdp_rtcp_unicast_mode_val[SDP_RTCP_MAX_UNICAST_MODE] =
|
|||
{"rsi", sizeof("rsi")}
|
||||
};
|
||||
|
||||
#define SDP_NAME(x) {x, sizeof(x)}
|
||||
/* Maintain the same order as defined in typdef sdp_rtcp_fb_type_e */
|
||||
const sdp_namearray_t sdp_rtcp_fb_type_val[SDP_MAX_RTCP_FB] =
|
||||
{
|
||||
SDP_NAME("ack"),
|
||||
SDP_NAME("ccm"),
|
||||
SDP_NAME("nack"),
|
||||
SDP_NAME("trr-int")
|
||||
};
|
||||
|
||||
/* Maintain the same order as defined in typdef sdp_rtcp_fb_nack_type_e */
|
||||
const sdp_namearray_t sdp_rtcp_fb_nack_type_val[SDP_MAX_RTCP_FB_NACK] =
|
||||
{
|
||||
SDP_NAME(""),
|
||||
SDP_NAME("sli"),
|
||||
SDP_NAME("pli"),
|
||||
SDP_NAME("rpsi"),
|
||||
SDP_NAME("app"),
|
||||
SDP_NAME("rai"),
|
||||
SDP_NAME("tllei"),
|
||||
SDP_NAME("pslei"),
|
||||
SDP_NAME("ecn")
|
||||
};
|
||||
|
||||
/* Maintain the same order as defined in typdef sdp_rtcp_fb_ack_type_e */
|
||||
const sdp_namearray_t sdp_rtcp_fb_ack_type_val[SDP_MAX_RTCP_FB_ACK] =
|
||||
{
|
||||
SDP_NAME("rpsi"),
|
||||
SDP_NAME("app")
|
||||
};
|
||||
|
||||
/* Maintain the same order as defined in typdef sdp_rtcp_fb_ccm_type_e */
|
||||
const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[SDP_MAX_RTCP_FB_CCM] =
|
||||
{
|
||||
SDP_NAME("fir"),
|
||||
SDP_NAME("tmmbr"),
|
||||
SDP_NAME("tstr"),
|
||||
SDP_NAME("vbcm")
|
||||
};
|
||||
|
||||
|
||||
/* Maintain same order as defined in typedef sdp_srtp_crypto_suite_t */
|
||||
const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] =
|
||||
{
|
||||
|
|
|
@ -33,6 +33,11 @@ extern const sdp_namearray_t sdp_bw_modifier_val[];
|
|||
extern const sdp_namearray_t sdp_group_attr_val[];
|
||||
extern const sdp_namearray_t sdp_src_filter_mode_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_unicast_mode_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_type_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_nack_type_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_ack_type_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[];
|
||||
|
||||
|
||||
extern const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[];
|
||||
/* Function Prototypes */
|
||||
|
@ -138,6 +143,12 @@ extern sdp_result_e sdp_parse_attr_srtpcontext(sdp_t *sdp_p,
|
|||
extern sdp_result_e sdp_build_attr_srtpcontext(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs);
|
||||
extern sdp_result_e sdp_parse_attr_rtcp_fb(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr);
|
||||
extern sdp_result_e sdp_build_attr_rtcp_fb(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs);
|
||||
extern sdp_result_e sdp_parse_attr_mptime(
|
||||
sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr);
|
||||
extern sdp_result_e sdp_build_attr_mptime(
|
||||
|
|
|
@ -241,6 +241,7 @@ typedef enum {
|
|||
SDP_ATTR_RTCP_MUX,
|
||||
SDP_ATTR_DTLS_FINGERPRINT,
|
||||
SDP_ATTR_MAXPTIME,
|
||||
SDP_ATTR_RTCP_FB, /* RFC 4585 */
|
||||
SDP_MAX_ATTR_TYPES,
|
||||
SDP_ATTR_INVALID
|
||||
} sdp_attr_e;
|
||||
|
|
|
@ -129,6 +129,11 @@ LOCAL_INCLUDES += \
|
|||
-I$(topsrcdir)/media/mtransport \
|
||||
-I$(topsrcdir)/media/mtransport/test \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/include \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/sipcc/core/sdp \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/sipcc/cpr/include \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/sipcc/core/includes \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/common/browser_logging \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/media \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/media-conduit \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/mediapipeline \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/sipcc/include \
|
||||
|
@ -145,6 +150,7 @@ LIBS += $(MOZ_ZLIB_LIBS)
|
|||
endif
|
||||
|
||||
CPP_UNIT_TESTS = \
|
||||
sdp_unittests.cpp \
|
||||
signaling_unittests.cpp \
|
||||
mediapipeline_unittest.cpp \
|
||||
mediaconduit_unittests.cpp \
|
||||
|
|
|
@ -0,0 +1,479 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CSFLog.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nss.h"
|
||||
|
||||
#include "FakeMediaStreams.h"
|
||||
#include "FakeMediaStreamsImpl.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionCtx.h"
|
||||
|
||||
#include "mtransport_test_utils.h"
|
||||
MtransportTestUtils *test_utils;
|
||||
nsCOMPtr<nsIThread> gThread;
|
||||
|
||||
extern "C" {
|
||||
#include "sdp.h"
|
||||
#include "sdp_private.h"
|
||||
}
|
||||
|
||||
namespace test {
|
||||
|
||||
static bool SetupGlobalThread() {
|
||||
if (!gThread) {
|
||||
nsIThread *thread;
|
||||
|
||||
nsresult rv = NS_NewNamedThread("pseudo-main",&thread);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
gThread = thread;
|
||||
sipcc::PeerConnectionCtx::InitializeGlobal(gThread);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class SdpTest : public ::testing::Test {
|
||||
public:
|
||||
SdpTest() : sdp_ptr_(nullptr) {
|
||||
sdp_media_e supported_media[] = {
|
||||
SDP_MEDIA_AUDIO,
|
||||
SDP_MEDIA_VIDEO,
|
||||
SDP_MEDIA_APPLICATION,
|
||||
SDP_MEDIA_DATA,
|
||||
SDP_MEDIA_CONTROL,
|
||||
SDP_MEDIA_NAS_RADIUS,
|
||||
SDP_MEDIA_NAS_TACACS,
|
||||
SDP_MEDIA_NAS_DIAMETER,
|
||||
SDP_MEDIA_NAS_L2TP,
|
||||
SDP_MEDIA_NAS_LOGIN,
|
||||
SDP_MEDIA_NAS_NONE,
|
||||
SDP_MEDIA_IMAGE,
|
||||
};
|
||||
|
||||
config_p_ = sdp_init_config();
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(supported_media) / sizeof(sdp_media_e); i++) {
|
||||
sdp_media_supported(config_p_, supported_media[i], true);
|
||||
}
|
||||
sdp_nettype_supported(config_p_, SDP_NT_INTERNET, true);
|
||||
sdp_addrtype_supported(config_p_, SDP_AT_IP4, true);
|
||||
sdp_addrtype_supported(config_p_, SDP_AT_IP6, true);
|
||||
sdp_transport_supported(config_p_, SDP_TRANSPORT_RTPSAVPF, true);
|
||||
sdp_transport_supported(config_p_, SDP_TRANSPORT_UDPTL, true);
|
||||
sdp_require_session_name(config_p_, false);
|
||||
}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
ASSERT_TRUE(SetupGlobalThread());
|
||||
}
|
||||
|
||||
void SetUp() {
|
||||
final_level_ = 0;
|
||||
sdp_ptr_ = nullptr;
|
||||
}
|
||||
|
||||
static void TearDownTestCase() {
|
||||
gThread = nullptr;
|
||||
}
|
||||
|
||||
void ResetSdp() {
|
||||
if (!sdp_ptr_) {
|
||||
sdp_free_description(sdp_ptr_);
|
||||
}
|
||||
sdp_ptr_ = sdp_init_description("BogusPeerConnectionId", config_p_);
|
||||
}
|
||||
|
||||
void ParseSdp(const std::string &sdp_str) {
|
||||
char *bufp = const_cast<char *>(sdp_str.data());
|
||||
ResetSdp();
|
||||
ASSERT_EQ(sdp_parse(sdp_ptr_, &bufp, sdp_str.size()), SDP_SUCCESS);
|
||||
}
|
||||
|
||||
void InitLocalSdp() {
|
||||
ResetSdp();
|
||||
ASSERT_EQ(sdp_set_version(sdp_ptr_, 0), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_owner_username(sdp_ptr_, "-"), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_owner_sessionid(sdp_ptr_, "132954853"), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_owner_version(sdp_ptr_, "0"), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_owner_network_type(sdp_ptr_, SDP_NT_INTERNET),
|
||||
SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_owner_address_type(sdp_ptr_, SDP_AT_IP4), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_owner_address(sdp_ptr_, "198.51.100.7"), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_session_name(sdp_ptr_, "SDP Unit Test"), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_time_start(sdp_ptr_, "0"), SDP_SUCCESS);
|
||||
ASSERT_EQ(sdp_set_time_stop(sdp_ptr_, "0"), SDP_SUCCESS);
|
||||
}
|
||||
|
||||
std::string SerializeSdp() {
|
||||
flex_string fs;
|
||||
flex_string_init(&fs);
|
||||
EXPECT_EQ(sdp_build(sdp_ptr_, &fs), SDP_SUCCESS);
|
||||
std::string body(fs.buffer);
|
||||
flex_string_free(&fs);
|
||||
return body;
|
||||
}
|
||||
|
||||
// Returns "level" for new media section
|
||||
int AddNewMedia(sdp_media_e type) {
|
||||
final_level_++;
|
||||
EXPECT_EQ(sdp_insert_media_line(sdp_ptr_, final_level_), SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_set_conn_nettype(sdp_ptr_, final_level_, SDP_NT_INTERNET),
|
||||
SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_set_conn_addrtype(sdp_ptr_, final_level_, SDP_AT_IP4),
|
||||
SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_set_conn_address(sdp_ptr_, final_level_, "198.51.100.7"),
|
||||
SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_set_media_type(sdp_ptr_, final_level_, SDP_MEDIA_VIDEO),
|
||||
SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_set_media_transport(sdp_ptr_, final_level_,
|
||||
SDP_TRANSPORT_RTPAVP),
|
||||
SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_set_media_portnum(sdp_ptr_, final_level_, 12345, 0),
|
||||
SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_add_media_payload_type(sdp_ptr_, final_level_, 120,
|
||||
SDP_PAYLOAD_NUMERIC),
|
||||
SDP_SUCCESS);
|
||||
return final_level_;
|
||||
}
|
||||
|
||||
u16 AddNewRtcpFbAck(int level, sdp_rtcp_fb_ack_type_e type,
|
||||
u16 payload = SDP_ALL_PAYLOADS) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
|
||||
&inst_num), SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_attr_set_rtcp_fb_ack(sdp_ptr_, level, payload, inst_num,
|
||||
type), SDP_SUCCESS);
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
u16 AddNewRtcpFbNack(int level, sdp_rtcp_fb_nack_type_e type,
|
||||
u16 payload = SDP_ALL_PAYLOADS) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
|
||||
&inst_num), SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_attr_set_rtcp_fb_nack(sdp_ptr_, level, payload, inst_num,
|
||||
type), SDP_SUCCESS);
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
u16 AddNewRtcpTrrInt(int level, u32 interval,
|
||||
u16 payload = SDP_ALL_PAYLOADS) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
|
||||
&inst_num), SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_attr_set_rtcp_fb_trr_int(sdp_ptr_, level, payload, inst_num,
|
||||
interval), SDP_SUCCESS);
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
u16 AddNewRtcpFbCcm(int level, sdp_rtcp_fb_ccm_type_e type,
|
||||
u16 payload = SDP_ALL_PAYLOADS) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
|
||||
&inst_num), SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_attr_set_rtcp_fb_ccm(sdp_ptr_, level, payload, inst_num,
|
||||
type), SDP_SUCCESS);
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
protected:
|
||||
int final_level_;
|
||||
void *config_p_;
|
||||
sdp_t *sdp_ptr_;
|
||||
};
|
||||
|
||||
static const std::string kVideoSdp =
|
||||
"v=0\r\n"
|
||||
"o=- 137331303 2 IN IP4 127.0.0.1\r\n"
|
||||
"s=SIP Call\r\n"
|
||||
"t=0 0\r\n"
|
||||
"m=video 56436 RTP/SAVPF 120\r\n"
|
||||
"c=IN IP4 198.51.100.7\r\n"
|
||||
"a=rtpmap:120 VP8/90000\r\n";
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbAckRpsi) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack rpsi\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_ACK_RPSI);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbAckApp) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack app\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_ACK_APP);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbAckAppFoo) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack app foo\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_ACK_APP);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbAckFooBar) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack foo bar\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_ACK_UNKNOWN);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbAckFooBarBaz) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack foo bar baz\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_ACK_UNKNOWN);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNack) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackPli) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack pli\r\n");
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackSli) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack sli\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_SLI);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackRpsi) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack rpsi\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_RPSI);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackApp) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack app\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_APP);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackAppFoo) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack app foo\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_APP);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackAppFooBar) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack app foo bar\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_APP);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackFooBarBaz) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack foo bar baz\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_UNKNOWN);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbTrrInt0) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 trr-int 0\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 1), 0U);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbTrrInt123) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 trr-int 123\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 1), 123U);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmFir) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm fir\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_CCM_FIR);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmTmmbr) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm tmmbr\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_CCM_TMMBR);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmTmmbrSmaxpr) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm tmmbr smaxpr=456\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_CCM_TMMBR);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmTstr) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm tstr\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_CCM_TSTR);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmVbcm) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm vbcm 123 456 789\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_CCM_VBCM);
|
||||
// We don't currently parse out VBCM submessage types, since we don't have
|
||||
// any use for them.
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmFoo) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm foo\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_CCM_UNKNOWN);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbCcmFooBarBaz) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm foo bar baz\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_CCM_UNKNOWN);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbFoo) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 foo\r\n");
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbFooBar) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 foo bar\r\n");
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbFooBarBaz) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 foo bar baz\r\n");
|
||||
}
|
||||
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbKitchenSink) {
|
||||
ParseSdp(kVideoSdp +
|
||||
"a=rtcp-fb:120 ack rpsi\r\n"
|
||||
"a=rtcp-fb:120 ack app\r\n"
|
||||
"a=rtcp-fb:120 ack app foo\r\n"
|
||||
"a=rtcp-fb:120 ack foo bar\r\n"
|
||||
"a=rtcp-fb:120 ack foo bar baz\r\n"
|
||||
"a=rtcp-fb:120 nack\r\n"
|
||||
"a=rtcp-fb:120 nack pli\r\n"
|
||||
"a=rtcp-fb:120 nack sli\r\n"
|
||||
"a=rtcp-fb:120 nack rpsi\r\n"
|
||||
"a=rtcp-fb:120 nack app\r\n"
|
||||
"a=rtcp-fb:120 nack app foo\r\n"
|
||||
"a=rtcp-fb:120 nack app foo bar\r\n"
|
||||
"a=rtcp-fb:120 nack foo bar baz\r\n"
|
||||
"a=rtcp-fb:120 trr-int 0\r\n"
|
||||
"a=rtcp-fb:120 trr-int 123\r\n"
|
||||
"a=rtcp-fb:120 ccm fir\r\n"
|
||||
"a=rtcp-fb:120 ccm tmmbr\r\n"
|
||||
"a=rtcp-fb:120 ccm tmmbr smaxpr=456\r\n"
|
||||
"a=rtcp-fb:120 ccm tstr\r\n"
|
||||
"a=rtcp-fb:120 ccm vbcm 123 456 789\r\n"
|
||||
"a=rtcp-fb:120 ccm foo\r\n"
|
||||
"a=rtcp-fb:120 ccm foo bar baz\r\n"
|
||||
"a=rtcp-fb:120 foo\r\n"
|
||||
"a=rtcp-fb:120 foo bar\r\n"
|
||||
"a=rtcp-fb:120 foo bar baz\r\n");
|
||||
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_ACK_RPSI);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 2), SDP_RTCP_FB_ACK_APP);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 3), SDP_RTCP_FB_ACK_APP);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 4),
|
||||
SDP_RTCP_FB_ACK_UNKNOWN);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 5),
|
||||
SDP_RTCP_FB_ACK_UNKNOWN);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 6),
|
||||
SDP_RTCP_FB_ACK_NOT_FOUND);
|
||||
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 2),
|
||||
SDP_RTCP_FB_NACK_PLI);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 3),
|
||||
SDP_RTCP_FB_NACK_SLI);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 4),
|
||||
SDP_RTCP_FB_NACK_RPSI);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 5),
|
||||
SDP_RTCP_FB_NACK_APP);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 6),
|
||||
SDP_RTCP_FB_NACK_APP);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 7),
|
||||
SDP_RTCP_FB_NACK_APP);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 8),
|
||||
SDP_RTCP_FB_NACK_UNKNOWN);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 9),
|
||||
SDP_RTCP_FB_NACK_NOT_FOUND);
|
||||
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 1), 0U);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 2), 123U);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 3), 0xFFFFFFFF);
|
||||
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_CCM_FIR);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 2),
|
||||
SDP_RTCP_FB_CCM_TMMBR);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 3),
|
||||
SDP_RTCP_FB_CCM_TMMBR);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 4),
|
||||
SDP_RTCP_FB_CCM_TSTR);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 5),
|
||||
SDP_RTCP_FB_CCM_VBCM);
|
||||
// We don't currently parse out VBCM submessage types, since we don't have
|
||||
// any use for them.
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 6),
|
||||
SDP_RTCP_FB_CCM_UNKNOWN);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 7),
|
||||
SDP_RTCP_FB_CCM_UNKNOWN);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 8),
|
||||
SDP_RTCP_FB_CCM_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
/* TODO (abr@mozilla.com) These attribute adding test cases definitely need
|
||||
beefing up; for now, I'm testing the two use cases that we know
|
||||
we need right now. An exhaustive check of the various permutations
|
||||
will look similar to the parsing tests, above */
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNack) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_UNSPECIFIED, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmFir) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_FIR, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 ccm fir\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmFirAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_FIR);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ccm fir\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
/* TODO We need to test the pt=* use cases. */
|
||||
|
||||
} // End namespace test.
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
test_utils = new MtransportTestUtils();
|
||||
NSS_NoDB_Init(NULL);
|
||||
NSS_SetDomesticPolicy();
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
delete test_utils;
|
||||
|
||||
return result;
|
||||
}
|
|
@ -2004,8 +2004,16 @@ TEST_F(SignalingTest, CheckTrickleSdpChange)
|
|||
std::string::npos);
|
||||
ASSERT_NE(a2_.getRemoteDescription().find("\r\na=candidate"),
|
||||
std::string::npos);
|
||||
/* TODO (abr): These checks aren't quite right, since trickle ICE
|
||||
* can easily result in SDP that is semantically identical but
|
||||
* varies syntactically (in particularly, the ordering of attributes
|
||||
* withing an m-line section can be different). This needs to be updated
|
||||
* to be a semantic comparision between the SDP. Currently, these checks
|
||||
* will fail whenever we add any other attributes to the SDP, such as
|
||||
* RTCP MUX or RTCP feedback.
|
||||
ASSERT_EQ(a1_.getLocalDescription(),a2_.getRemoteDescription());
|
||||
ASSERT_EQ(a2_.getLocalDescription(),a1_.getRemoteDescription());
|
||||
*/
|
||||
}
|
||||
|
||||
TEST_F(SignalingTest, ipAddrAnyOffer)
|
||||
|
|
Загрузка…
Ссылка в новой задаче