Bug 881935 - Part 1: SDP parsing/building for max-fs and max-fr parameters. r=abr

This commit is contained in:
Shian-Yow Wu 2013-10-13 09:43:00 +08:00
Родитель 47445c3827
Коммит a56c9cd394
6 изменённых файлов: 211 добавлений и 4 удалений

Просмотреть файл

@ -1146,6 +1146,8 @@ gsmsdp_set_video_media_attributes (uint32_t media_type, void *cc_sdp_p, uint16_t
{
uint16_t a_inst;
void *sdp_p = ((cc_sdp_t*)cc_sdp_p)->src_sdp;
int max_fs = 0;
int max_fr = 0;
switch (media_type) {
case RTP_H263:
@ -1182,6 +1184,29 @@ gsmsdp_set_video_media_attributes (uint32_t media_type, void *cc_sdp_p, uint16_t
SIPSDP_ATTR_ENCNAME_VP8);
(void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst,
RTPMAP_VIDEO_CLOCKRATE);
/* TODO: Get max_fs & max_fr from device configuration (Bug 881935) */
if (max_fs || max_fr) {
if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst)
!= SDP_SUCCESS) {
GSM_ERR_MSG("Failed to add attribute");
return;
}
(void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst,
payload_number);
if (max_fs) {
(void) sdp_attr_set_fmtp_max_fs(sdp_p, level, 0, a_inst,
max_fs);
}
if (max_fr) {
(void) sdp_attr_set_fmtp_max_fr(sdp_p, level, 0, a_inst,
max_fr);
}
}
break;
}
GSM_DEBUG("gsmsdp_set_video_media_attributes- populate attribs %d", payload_number );

Просмотреть файл

@ -405,6 +405,7 @@ typedef enum {
SDP_USE_IN_BAND_FEC,
SDP_MAX_CODED_AUDIO_BW,
SDP_CBR,
SDP_MAX_FR,
SDP_MAX_FMTP_PARAM,
SDP_FMTP_PARAM_UNKNOWN
} sdp_fmtp_codec_param_e;
@ -680,6 +681,7 @@ typedef struct sdp_fmtp {
u32 max_mbps;
u32 max_fs;
u32 max_fr;
u32 max_cpb;
u32 max_dpb;
u32 max_br;
@ -1518,6 +1520,12 @@ extern sdp_result_e sdp_attr_set_fmtp_max_fs (void *sdp_ptr,
u16 inst_num,
u32 max_fs);
extern sdp_result_e sdp_attr_set_fmtp_max_fr (void *sdp_ptr,
u16 level,
u8 cap_num,
u16 inst_num,
u32 max_fr);
extern sdp_result_e sdp_attr_set_fmtp_max_cpb (void *sdp_ptr,
u16 level,
u8 cap_num,
@ -1694,6 +1702,8 @@ extern sdp_result_e sdp_attr_get_fmtp_max_mbps (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num, u32 *val);
extern sdp_result_e sdp_attr_get_fmtp_max_fs (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num, u32 *val);
extern sdp_result_e sdp_attr_get_fmtp_max_fr (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num, u32 *val);
extern sdp_result_e sdp_attr_get_fmtp_max_cpb (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num, u32 *val);
extern sdp_result_e sdp_attr_get_fmtp_max_dpb (void *sdp_ptr, u16 level,

Просмотреть файл

@ -1222,7 +1222,7 @@ sdp_result_e sdp_parse_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p,
if (result1 != SDP_SUCCESS) {
fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1);
if (result1 != SDP_SUCCESS) {
sdp_attr_fmtp_no_value(sdp_p, "max_fs");
sdp_attr_fmtp_no_value(sdp_p, "max-fs");
SDP_FREE(temp_ptr);
return SDP_INVALID_PARAMETER;
}
@ -1234,7 +1234,7 @@ sdp_result_e sdp_parse_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p,
strtoul_result = strtoul(tok, &strtoul_end, 10);
if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) {
sdp_attr_fmtp_invalid_value(sdp_p, "max_fs", tok);
sdp_attr_fmtp_invalid_value(sdp_p, "max-fs", tok);
SDP_FREE(temp_ptr);
return SDP_INVALID_PARAMETER;
}
@ -1692,7 +1692,32 @@ sdp_result_e sdp_parse_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p,
fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO;
fmtp_p->cbr = (u16) strtoul_result;
codec_info_found = TRUE;
} else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[49].name,
sdp_fmtp_codec_param[49].strlen) == 0) {
fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t",
&result1);
if (result1 != SDP_SUCCESS) {
fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp),
" \t", &result1);
if (result1 != SDP_SUCCESS) {
sdp_attr_fmtp_no_value(sdp_p, "max-fr");
SDP_FREE(temp_ptr);
return SDP_INVALID_PARAMETER;
}
}
tok = tmp;
tok++;
errno = 0;
strtoul_result = strtoul(tok, &strtoul_end, 10);
if (errno || tok == strtoul_end || strtoul_result == 0 ||
strtoul_result > UINT_MAX) {
sdp_attr_fmtp_invalid_value(sdp_p, "max-fr", tok);
SDP_FREE(temp_ptr);
return SDP_INVALID_PARAMETER;
}
fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO;
fmtp_p->max_fr = (u32) strtoul_result;
codec_info_found = TRUE;
} else if (fmtp_ptr != NULL && *fmtp_ptr == '\n') {
temp=PL_strtok_r(tmp, ";", &strtok_state);
if (temp) {
@ -1999,6 +2024,8 @@ sdp_result_e sdp_build_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string
FMTP_BUILD_UNSIGNED(fmtp_p->max_fs > 0, "max-fs", fmtp_p->max_fs)
FMTP_BUILD_UNSIGNED(fmtp_p->max_fr > 0, "max-fr", fmtp_p->max_fr)
FMTP_BUILD_UNSIGNED(fmtp_p->max_cpb > 0, "max-cpb", fmtp_p->max_cpb)
FMTP_BUILD_UNSIGNED(fmtp_p->max_dpb > 0, "max-dpb", fmtp_p->max_dpb)

Просмотреть файл

@ -457,6 +457,7 @@ void sdp_copy_attr_fields (sdp_attr_t *src_attr_p, sdp_attr_t *dst_attr_p)
dst_attr_p->attr.fmtp.max_mbps = src_attr_p->attr.fmtp.max_mbps;
dst_attr_p->attr.fmtp.max_fs = src_attr_p->attr.fmtp.max_fs;
dst_attr_p->attr.fmtp.max_fr = src_attr_p->attr.fmtp.max_fr;
dst_attr_p->attr.fmtp.max_cpb = src_attr_p->attr.fmtp.max_cpb;
dst_attr_p->attr.fmtp.max_dpb = src_attr_p->attr.fmtp.max_dpb;
dst_attr_p->attr.fmtp.max_br = src_attr_p->attr.fmtp.max_br;
@ -862,6 +863,7 @@ sdp_result_e sdp_copy_attr (void *src_sdp_ptr, void *dst_sdp_ptr,
new_attr_p->attr.fmtp.max_mbps = src_attr_p->attr.fmtp.max_mbps;
new_attr_p->attr.fmtp.max_fs = src_attr_p->attr.fmtp.max_fs;
new_attr_p->attr.fmtp.max_fr = src_attr_p->attr.fmtp.max_fr;
new_attr_p->attr.fmtp.max_cpb = src_attr_p->attr.fmtp.max_cpb;
new_attr_p->attr.fmtp.max_dpb = src_attr_p->attr.fmtp.max_dpb;
new_attr_p->attr.fmtp.max_br = src_attr_p->attr.fmtp.max_br;
@ -6361,6 +6363,39 @@ sdp_result_e sdp_attr_set_fmtp_max_fs (void *sdp_ptr, u16 level,
}
}
sdp_result_e sdp_attr_set_fmtp_max_fr (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num,
u32 max_fr)
{
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
sdp_attr_t *attr_p;
sdp_fmtp_t *fmtp_p;
if (sdp_verify_sdp_ptr(sdp_p) == FALSE) {
return (SDP_INVALID_PARAMETER);
}
attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num);
if (attr_p == NULL) {
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
CSFLogError(logTag, "%s fmtp attribute, level %u instance %u "
"not found.", sdp_p->debug_str, level, inst_num);
}
sdp_p->conf_p->num_invalid_param++;
return (SDP_INVALID_PARAMETER);
}
fmtp_p = &(attr_p->attr.fmtp);
fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO;
if (max_fr > 0) {
fmtp_p->max_fr = max_fr;
return (SDP_SUCCESS);
} else {
return (SDP_FAILURE);
}
}
sdp_result_e sdp_attr_set_fmtp_max_br (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num,
u32 max_br)
@ -8265,6 +8300,41 @@ sdp_result_e sdp_attr_get_fmtp_max_fs (void *sdp_ptr, u16 level,
}
}
/* Function: sdp_attr_get_fmtp_max_fr
* Description: Gets the value of the fmtp attribute- max-fr parameter
* 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: max-fr value.
*/
sdp_result_e sdp_attr_get_fmtp_max_fr (void *sdp_ptr, u16 level,
u8 cap_num, u16 inst_num, u32 *val)
{
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
sdp_attr_t *attr_p;
if (sdp_verify_sdp_ptr(sdp_p) == FALSE) {
return (SDP_INVALID_SDP_PTR);
}
attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP,
inst_num);
if (attr_p == NULL) {
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
CSFLogError(logTag, "%s fmtp attribute, level %u instance %u "
"not found.", sdp_p->debug_str, level, inst_num);
}
sdp_p->conf_p->num_invalid_param++;
return (SDP_INVALID_PARAMETER);
} else {
*val = attr_p->attr.fmtp.max_fr;
return (SDP_SUCCESS);
}
}
/* Function: sdp_attr_get_fmtp_max_cpb
* Description: Gets the value of the fmtp attribute- max-cpb parameter for H.264 codec
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.

Просмотреть файл

@ -400,7 +400,8 @@ const sdp_namearray_t sdp_fmtp_codec_param[SDP_MAX_FMTP_PARAM] =
{"stereo", sizeof("stereo")}, /* 45 */
{"useinbandfec", sizeof("useinbandfec")}, /* 46 */
{"maxcodedaudiobandwidth", sizeof("maxcodedaudiobandwidth")}, /* 47 */
{"cbr", sizeof("cbr")} /* 48 */
{"cbr", sizeof("cbr")}, /* 48 */
{"max-fr", sizeof("max-fr")} /* 49 */
} ;
/* Note: These *must* be in the same order as the enum type. */

Просмотреть файл

@ -190,6 +190,41 @@ class SdpTest : public ::testing::Test {
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,
&inst_num), SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num,
120), SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_max_fs(sdp_ptr_, level, 0, inst_num, max_fs),
SDP_SUCCESS);
return inst_num;
}
u16 AddNewFmtpMaxFr(int level, u32 max_fr) {
u16 inst_num = 0;
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP,
&inst_num), SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num,
120), SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_max_fr(sdp_ptr_, level, 0, inst_num, max_fr),
SDP_SUCCESS);
return inst_num;
}
u16 AddNewFmtpMaxFsFr(int level, u32 max_fs, u32 max_fr) {
u16 inst_num = 0;
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP,
&inst_num), SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num,
120), SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_max_fs(sdp_ptr_, level, 0, inst_num, max_fs),
SDP_SUCCESS);
EXPECT_EQ(sdp_attr_set_fmtp_max_fr(sdp_ptr_, level, 0, inst_num, max_fr),
SDP_SUCCESS);
return inst_num;
}
protected:
int final_level_;
void *config_p_;
@ -689,6 +724,45 @@ TEST_F(SdpTest, parseRtcpFbAllPayloads) {
}
}
TEST_F(SdpTest, parseFmtpMaxFs) {
u32 val = 0;
ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n");
ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS);
ASSERT_EQ(val, 300);
}
TEST_F(SdpTest, parseFmtpMaxFr) {
u32 val = 0;
ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n");
ASSERT_EQ(sdp_attr_get_fmtp_max_fr(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS);
ASSERT_EQ(val, 30);
}
TEST_F(SdpTest, addFmtpMaxFs) {
InitLocalSdp();
int level = AddNewMedia(SDP_MEDIA_VIDEO);
AddNewFmtpMaxFs(level, 300);
std::string body = SerializeSdp();
ASSERT_NE(body.find("a=fmtp:120 max-fs=300\r\n"), std::string::npos);
}
TEST_F(SdpTest, addFmtpMaxFr) {
InitLocalSdp();
int level = AddNewMedia(SDP_MEDIA_VIDEO);
AddNewFmtpMaxFr(level, 30);
std::string body = SerializeSdp();
ASSERT_NE(body.find("a=fmtp:120 max-fr=30\r\n"), std::string::npos);
}
TEST_F(SdpTest, addFmtpMaxFsFr) {
InitLocalSdp();
int level = AddNewMedia(SDP_MEDIA_VIDEO);
AddNewFmtpMaxFsFr(level, 300, 30);
std::string body = SerializeSdp();
ASSERT_NE(body.find("a=fmtp:120 max-fs=300;max-fr=30\r\n"),
std::string::npos);
}
} // End namespace test.
int main(int argc, char **argv) {