mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 966885 - Enable audio level RTP extension. r=jesup, r=ehugg
This commit is contained in:
parent
23c4f9b1c3
commit
f79791737a
@ -76,6 +76,10 @@ WebrtcAudioConduit::~WebrtcAudioConduit()
|
||||
|
||||
delete mCurSendCodecConfig;
|
||||
|
||||
if (mPtrVoERTP_RTCP) {
|
||||
mPtrVoERTP_RTCP->Release();
|
||||
}
|
||||
|
||||
// The first one of a pair to be deleted shuts down media for both
|
||||
if(mPtrVoEXmedia)
|
||||
{
|
||||
@ -285,6 +289,12 @@ MediaConduitErrorCode WebrtcAudioConduit::Init(WebrtcAudioConduit *other)
|
||||
return kMediaConduitSessionNotInited;
|
||||
}
|
||||
|
||||
if(!(mPtrVoERTP_RTCP = VoERTP_RTCP::GetInterface(mVoiceEngine)))
|
||||
{
|
||||
CSFLogError(logTag, "%s Unable to initialize VoERTP_RTCP", __FUNCTION__);
|
||||
return kMediaConduitSessionNotInited;
|
||||
}
|
||||
|
||||
if(!(mPtrVoEVideoSync = VoEVideoSync::GetInterface(mVoiceEngine)))
|
||||
{
|
||||
CSFLogError(logTag, "%s Unable to initialize VoEVideoSync", __FUNCTION__);
|
||||
@ -563,6 +573,20 @@ WebrtcAudioConduit::ConfigureRecvMediaCodecs(
|
||||
return kMediaConduitNoError;
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
WebrtcAudioConduit::EnableAudioLevelExtension(bool enabled)
|
||||
{
|
||||
CSFLogDebug(logTag, "%s %d ", __FUNCTION__, enabled);
|
||||
|
||||
if (mPtrVoERTP_RTCP->SetRTPAudioLevelIndicationStatus(mChannel, enabled, 1) == -1)
|
||||
{
|
||||
CSFLogError(logTag, "%s SetRTPAudioLevelIndicationStatus Failed", __FUNCTION__);
|
||||
return kMediaConduitUnknownError;
|
||||
}
|
||||
|
||||
return kMediaConduitNoError;
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
WebrtcAudioConduit::SendAudioFrame(const int16_t audio_data[],
|
||||
int32_t lengthSamples,
|
||||
|
@ -31,6 +31,7 @@
|
||||
using webrtc::VoEExternalMedia;
|
||||
using webrtc::VoEAudioProcessing;
|
||||
using webrtc::VoEVideoSync;
|
||||
using webrtc::VoERTP_RTCP;
|
||||
|
||||
/** This file hosts several structures identifying different aspects
|
||||
* of a RTP Session.
|
||||
@ -87,6 +88,12 @@ public:
|
||||
virtual MediaConduitErrorCode ConfigureRecvMediaCodecs(
|
||||
const std::vector<AudioCodecConfig* >& codecConfigList);
|
||||
|
||||
/**
|
||||
* Function to enable the audio level extension
|
||||
* @param enabled: enable extension
|
||||
*/
|
||||
virtual MediaConduitErrorCode EnableAudioLevelExtension(bool enabled);
|
||||
|
||||
/**
|
||||
* Register External Transport to this Conduit. RTP and RTCP frames from the VoiceEngine
|
||||
* shall be passed to the registered transport for transporting externally.
|
||||
@ -234,6 +241,7 @@ private:
|
||||
webrtc::VoEExternalMedia* mPtrVoEXmedia;
|
||||
webrtc::VoEAudioProcessing* mPtrVoEProcessing;
|
||||
webrtc::VoEVideoSync* mPtrVoEVideoSync;
|
||||
webrtc::VoERTP_RTCP* mPtrVoERTP_RTCP;
|
||||
webrtc::VoERTP_RTCP* mPtrRTP;
|
||||
|
||||
//engine states of our interets
|
||||
|
@ -345,6 +345,13 @@ public:
|
||||
virtual MediaConduitErrorCode ConfigureRecvMediaCodecs(
|
||||
const std::vector<AudioCodecConfig* >& recvCodecConfigList) = 0;
|
||||
|
||||
/**
|
||||
* Function to enable the audio level extension
|
||||
* @param enabled: enable extension
|
||||
* NOTE: See AudioConduit for more information
|
||||
*/
|
||||
virtual MediaConduitErrorCode EnableAudioLevelExtension(bool enabled) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -2234,6 +2234,11 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
||||
if (!conduit || conduit->ConfigureSendMediaCodec(config))
|
||||
return VCM_ERROR;
|
||||
|
||||
CSFLogError(logTag, "Created audio pipeline audio level %d", attrs->audio_level);
|
||||
|
||||
if (!conduit || conduit->EnableAudioLevelExtension(attrs->audio_level))
|
||||
return VCM_ERROR;
|
||||
|
||||
pc.impl()->media()->AddConduit(level, false, conduit);
|
||||
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
|
||||
|
@ -521,6 +521,7 @@ gsmsdp_init_media (fsmdef_media_t *media)
|
||||
media->video = NULL;
|
||||
media->candidate_ct = 0;
|
||||
media->rtcp_mux = FALSE;
|
||||
media->audio_level = TRUE;
|
||||
|
||||
/* ACTPASS is the value we put in every offer */
|
||||
media->setup = SDP_SETUP_ACTPASS;
|
||||
@ -1710,6 +1711,40 @@ gsmsdp_set_rtcp_fb_ack_attribute (uint16_t level,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gsmsdp_set_audio_level_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds an audio level extension attributesto 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 attribute against.
|
||||
*/
|
||||
void
|
||||
gsmsdp_set_extmap_attribute (uint16_t level,
|
||||
void *sdp_p,
|
||||
u16 id,
|
||||
const char* uri)
|
||||
{
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_EXTMAP, &a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_extmap(sdp_p, level, id, uri, a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_rtcp_fb_nack_attribute
|
||||
*
|
||||
@ -4633,6 +4668,57 @@ gsmsdp_negotiate_rtcp_fb (cc_sdp_t *cc_sdp_p,
|
||||
return CC_CAUSE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gsmsdp_negotiate_extmap
|
||||
*
|
||||
* Description:
|
||||
* Negotiates extmaps header extension to local SDP for supported audio codecs
|
||||
*
|
||||
* Parameters:
|
||||
* cc_sdp_p - local and remote SDP
|
||||
* media - The media structure for the current level to be negotiated
|
||||
* offer - True if the remote SDP is an offer
|
||||
*
|
||||
* returns
|
||||
* CC_CAUSE_OK - success
|
||||
* any other code - failure
|
||||
*/
|
||||
cc_causes_t
|
||||
gsmsdp_negotiate_extmap (cc_sdp_t *cc_sdp_p,
|
||||
fsmdef_media_t *media,
|
||||
boolean offer)
|
||||
{
|
||||
boolean audio_level = FALSE;
|
||||
int level = media->level;
|
||||
int i;
|
||||
const char* uri;
|
||||
|
||||
/*
|
||||
* Remove any previously negotiated extmap attributes from the
|
||||
* local SDP
|
||||
*/
|
||||
sdp_result_e result = SDP_SUCCESS;
|
||||
while (result == SDP_SUCCESS) {
|
||||
result = sdp_delete_attr (cc_sdp_p->src_sdp, level, 0,
|
||||
SDP_ATTR_EXTMAP, 1);
|
||||
}
|
||||
|
||||
i = 1;
|
||||
do {
|
||||
uri = sdp_attr_get_extmap_uri(cc_sdp_p->dest_sdp, level, 0, i);
|
||||
|
||||
if (uri != NULL && strcmp(uri, SDP_EXTMAP_AUDIO_LEVEL) == 0) {
|
||||
audio_level = TRUE;
|
||||
}
|
||||
i++;
|
||||
} while (uri != NULL);
|
||||
|
||||
media->audio_level = audio_level;
|
||||
|
||||
return CC_CAUSE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_negotiate_media_lines
|
||||
*
|
||||
@ -4986,6 +5072,11 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
|
||||
gsmsdp_negotiate_rtcp_fb (dcb_p->sdp, media, offer);
|
||||
}
|
||||
|
||||
/* Negotiate redundancy mechanisms */
|
||||
if (media && media_type == SDP_MEDIA_AUDIO) {
|
||||
gsmsdp_negotiate_extmap (dcb_p->sdp, media, offer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Negotiate rtcp-mux
|
||||
*/
|
||||
@ -5598,6 +5689,12 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
|
||||
sdp_rtcp_fb_ccm_to_bitmap(SDP_RTCP_FB_CCM_FIR));
|
||||
}
|
||||
|
||||
/* Add supported audio level rtp extension */
|
||||
if (media_cap->type == SDP_MEDIA_AUDIO) {
|
||||
gsmsdp_set_extmap_attribute(level, dcb_p->sdp->src_sdp, 1,
|
||||
SDP_EXTMAP_AUDIO_LEVEL);
|
||||
}
|
||||
|
||||
/* Add a=setup attribute */
|
||||
gsmsdp_set_setup_attribute(level, dcb_p->sdp->src_sdp, media->setup);
|
||||
|
||||
|
@ -207,6 +207,9 @@ typedef struct fsmdef_media_t_ {
|
||||
*/
|
||||
boolean rtcp_mux;
|
||||
|
||||
/* Flag to indicate if RTP Header extension for audio level is used */
|
||||
boolean audio_level;
|
||||
|
||||
/*
|
||||
* The value of the a=setup line
|
||||
*/
|
||||
|
@ -1236,6 +1236,7 @@ lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
|
||||
attrs.mute = FALSE;
|
||||
|
||||
attrs.rtcp_mux = media->rtcp_mux;
|
||||
attrs.audio_level = media->audio_level;
|
||||
|
||||
attrs.is_video = FALSE;
|
||||
attrs.bundle_level = 0;
|
||||
|
@ -74,6 +74,8 @@
|
||||
#define SDP_CONTEXT_RESET_MASTER_KEY(cw) ((cw) &= ~(SDP_SRTCP_KEY_MASK))
|
||||
#define SDP_CONTEXT_RESET_MASTER_SALT(cw) ((cw) &= ~(SDP_SRTCP_SALT_MASK))
|
||||
|
||||
#define SDP_EXTMAP_AUDIO_LEVEL "urn:ietf:params:rtp-hdrext:ssrc-audio-level"
|
||||
|
||||
/* SDP Enum Types */
|
||||
|
||||
typedef enum {
|
||||
@ -893,6 +895,18 @@ typedef struct sdp_media_profiles {
|
||||
u16 payload_type[SDP_MAX_PROFILES][SDP_MAX_PAYLOAD_TYPES];
|
||||
} sdp_media_profiles_t;
|
||||
|
||||
/*
|
||||
* a=extmap:<value>["/"<direction>] <URI> <extensionattributes>
|
||||
*
|
||||
*/
|
||||
typedef struct sdp_extmap {
|
||||
u16 id;
|
||||
sdp_direction_e media_direction;
|
||||
char uri[SDP_MAX_STRING_LEN+1];
|
||||
char extension_attributes[SDP_MAX_STRING_LEN+1];
|
||||
} sdp_extmap_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* sdp_srtp_crypto_context_t
|
||||
@ -982,6 +996,7 @@ typedef struct sdp_attr {
|
||||
sdp_fmtp_fb_t rtcp_fb;
|
||||
sdp_setup_type_e setup;
|
||||
sdp_connection_type_e connection;
|
||||
sdp_extmap_t extmap;
|
||||
} attr;
|
||||
struct sdp_attr *next_p;
|
||||
} sdp_attr_t;
|
||||
@ -2104,4 +2119,10 @@ 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);
|
||||
|
||||
const char *
|
||||
sdp_attr_get_extmap_uri(void *sdp_ptr, u16 level, u16 id, u16 inst);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_extmap(void *sdp_ptr, u16 level, u16 id, const char* uri, u16 inst);
|
||||
|
||||
#endif /* _SDP_H_ */
|
||||
|
@ -5148,3 +5148,77 @@ sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p,
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_build_attr_extmap(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs)
|
||||
{
|
||||
flex_string_sprintf(fs, "a=extmap:%d %s\r\n",
|
||||
attr_p->attr.extmap.id,
|
||||
attr_p->attr.extmap.uri);
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_parse_attr_extmap(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr)
|
||||
{
|
||||
sdp_result_e result;
|
||||
|
||||
attr_p->attr.extmap.id = 0;
|
||||
attr_p->attr.extmap.media_direction = SDP_DIRECTION_SENDRECV;
|
||||
attr_p->attr.extmap.uri[0] = '\0';
|
||||
attr_p->attr.extmap.extension_attributes[0] = '\0';
|
||||
|
||||
/* Find the payload type number. */
|
||||
attr_p->attr.extmap.id =
|
||||
(u16)sdp_getnextnumtok(ptr, &ptr, "/ \t", &result);
|
||||
if (result != SDP_SUCCESS) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: Invalid extmap id specified for %s attribute.",
|
||||
sdp_p->debug_str, sdp_get_attr_name(attr_p->type));
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
if (*ptr == '/') {
|
||||
char direction[SDP_MAX_STRING_LEN+1];
|
||||
/* Find the encoding name. */
|
||||
ptr = sdp_getnextstrtok(ptr, direction,
|
||||
sizeof(direction), " \t", &result);
|
||||
if (result != SDP_SUCCESS) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: No uri specified in %s attribute.",
|
||||
sdp_p->debug_str, sdp_get_attr_name(attr_p->type));
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
ptr = sdp_getnextstrtok(ptr, attr_p->attr.extmap.uri,
|
||||
sizeof(attr_p->attr.extmap.uri), " \t", &result);
|
||||
if (result != SDP_SUCCESS) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: No uri specified in %s attribute.",
|
||||
sdp_p->debug_str, sdp_get_attr_name(attr_p->type));
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (SDP_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
ptr = sdp_getnextstrtok(ptr, attr_p->attr.extmap.extension_attributes,
|
||||
sizeof(attr_p->attr.extmap.extension_attributes), "\r\n", &result);
|
||||
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
|
||||
SDP_PRINT("%s Parsed a=%s, id %u, direction %s, "
|
||||
"uri %s, extension %s", sdp_p->debug_str,
|
||||
sdp_get_attr_name(attr_p->type),
|
||||
attr_p->attr.extmap.id,
|
||||
SDP_DIRECTION_PRINT(attr_p->attr.extmap.media_direction),
|
||||
attr_p->attr.extmap.uri,
|
||||
attr_p->attr.extmap.extension_attributes);
|
||||
}
|
||||
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -12484,3 +12484,76 @@ sdp_attr_set_rtcp_fb_ccm(void *sdp_ptr, u16 level, u16 payload_type, u16 inst,
|
||||
attr_p->attr.rtcp_fb.extra[0] = '\0';
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_extmap_uri
|
||||
* Description: Returns a pointer to the value of the encoding name
|
||||
* parameter specified for the given attribute. Value is
|
||||
* returned as a const ptr and so cannot be modified by the
|
||||
* application. If the given attribute is not defined, NULL
|
||||
* will be returned.
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* cap_num The capability number associated with the
|
||||
* attribute if any. If none, should be zero.
|
||||
* inst_num The attribute instance number to check.
|
||||
* Returns: Codec value or SDP_CODEC_INVALID.
|
||||
*/
|
||||
const char *sdp_attr_get_extmap_uri(void *sdp_ptr, u16 level,
|
||||
u16 id, u16 inst_num)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (sdp_verify_sdp_ptr(sdp_p) == FALSE) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, id, SDP_ATTR_EXTMAP, inst_num);
|
||||
if (attr_p == NULL) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s extmap attribute, level %u instance %u "
|
||||
"not found.", sdp_p->debug_str, level, inst_num);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return (NULL);
|
||||
} else {
|
||||
return (attr_p->attr.extmap.uri);
|
||||
}
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_set_extmap
|
||||
* 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.
|
||||
* id The id to set the attribute.
|
||||
* uri The uri to set the attribute.
|
||||
* inst The attribute instance number to check.
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_extmap(void *sdp_ptr, u16 level, u16 id, const char* uri, u16 inst)
|
||||
{
|
||||
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_EXTMAP, inst);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s extmap 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.extmap.id = id;
|
||||
sstrncpy(attr_p->attr.extmap.uri, uri, SDP_MAX_STRING_LEN+1);
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,8 @@ const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] =
|
||||
sdp_parse_attr_setup, sdp_build_attr_setup},
|
||||
{"connection", sizeof("connection"),
|
||||
sdp_parse_attr_connection, sdp_build_attr_connection},
|
||||
{"extmap", sizeof("extmap"),
|
||||
sdp_parse_attr_extmap, sdp_build_attr_extmap},
|
||||
};
|
||||
|
||||
/* Note: These *must* be in the same order as the enum types. */
|
||||
|
@ -167,6 +167,12 @@ extern sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p,
|
||||
extern sdp_result_e sdp_build_attr_connection(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs);
|
||||
extern sdp_result_e sdp_parse_attr_extmap(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr);
|
||||
extern sdp_result_e sdp_build_attr_extmap(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(
|
||||
|
@ -246,6 +246,7 @@ typedef enum {
|
||||
SDP_ATTR_RTCP_FB, /* RFC 4585 */
|
||||
SDP_ATTR_SETUP,
|
||||
SDP_ATTR_CONNECTION,
|
||||
SDP_ATTR_EXTMAP, /* RFC 5285 */
|
||||
SDP_MAX_ATTR_TYPES,
|
||||
SDP_ATTR_INVALID
|
||||
} sdp_attr_e;
|
||||
|
@ -338,6 +338,7 @@ typedef struct vcm_attrs_t_ {
|
||||
cc_boolean mute;
|
||||
cc_boolean is_video;
|
||||
cc_boolean rtcp_mux;
|
||||
cc_boolean audio_level;
|
||||
vcm_audioAttrs_t audio; /**< audio line attribs */
|
||||
vcm_videoAttrs_t video; /**< Video Atrribs */
|
||||
uint32_t bundle_level; /**< Where bundle transport info lives, if any */
|
||||
|
@ -192,6 +192,15 @@ class SdpTest : public ::testing::Test {
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
u16 AddNewExtMap(int level, const char* uri) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_EXTMAP,
|
||||
&inst_num), SDP_SUCCESS);
|
||||
EXPECT_EQ(sdp_attr_set_extmap(sdp_ptr_, level, 0,
|
||||
uri, inst_num), SDP_SUCCESS);
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
u16 AddNewFmtpMaxFs(int level, u32 max_fs) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP,
|
||||
@ -726,6 +735,21 @@ TEST_F(SdpTest, parseRtcpFbAllPayloads) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addExtMap) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewExtMap(level, SDP_EXTMAP_AUDIO_LEVEL);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseExtMap) {
|
||||
ParseSdp(kVideoSdp +
|
||||
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n");
|
||||
ASSERT_STREQ(sdp_attr_get_extmap_uri(sdp_ptr_, 1, 0, 1),
|
||||
SDP_EXTMAP_AUDIO_LEVEL);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseFmtpMaxFs) {
|
||||
u32 val = 0;
|
||||
ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n");
|
||||
|
Loading…
Reference in New Issue
Block a user