📄 sdp_decode.c
字号:
temp =(char*)strsep(&slash, " \t/");
if (temp == NULL) {
Rtsp_Printf( "Can't find seperator after encode name in rtpmap\n");
return (-1);
}
if (sscanf(temp, "%u", &a) == 0) {
Rtsp_Printf( "Couldn't decode rtp clockrate %s\n", temp);
return (-1);
}
b = 0;
if (slash != NULL) {
ADV_SPACE(slash);
if (*slash == '/') {
slash++;
ADV_SPACE(slash);
}
if (isdigit(*slash)) {
sscanf(slash, "%u", &b);
}
}
} else {
Rtsp_Printf( "a=rtpmap clock rate is missing.\n");
Rtsp_Printf( "Most likely, you're decoding SDP from Apple's broadcaster\n");
Rtsp_Printf( "They initially misinterpreted RFC3016, but should fix it at some point\n");
Rtsp_Printf( "You may see audio/video at the wrong rate\n");
a = 90000;
b = 0;
}
fptr->rtpmap = Rtsp_Malloc(sizeof(rtpmap_desc_t),__LINE__,__FILE__);
if (fptr->rtpmap == NULL)
return (-1);
fptr->rtpmap->encode_name = strdup(enc);
fptr->rtpmap->clock_rate = a;
fptr->rtpmap->encode_param = b;
return (0);
}
/*
* sdp_decode_parse_a_cat()
* parses a=category:foo.bar...
*/
static int sdp_decode_parse_a_cat (int arg,
char *orig_line,
session_desc_t *sptr,
media_desc_t *mptr)
{
char *sep, *line, *lptr;
int errret;
uint32_t cat;
category_list_t *cptr, *new;
if (sptr->category_list != NULL) {
return (-1);
}
errret = 0;
cptr = NULL; /* shut up compiler*/
line =strdup(orig_line);
lptr = line;
while (NULL!=(sep =(char*)strsep(&lptr, " \t."))) {
if (*sep != '\0') {
cat = 0;
while (isdigit(*sep)) {
cat *= 10;
cat += *sep - '0';
sep++;
}
if (cat == 0) {
break;
}
new = Rtsp_Malloc(sizeof(category_list_t),__LINE__,__FILE__);
if (new == NULL) {
break;
}
new->category = cat;
new->next = NULL;
if (sptr->category_list == NULL) {
cptr = sptr->category_list = new;
} else {
cptr->next = new;
cptr = new;
}
}
}
if (errret != 0) {
free_category_list(&sptr->category_list);
}
Rtsp_Free(line,__LINE__,__FILE__);
return (errret);
}
/*
* sdp_decode_parse_a_frame()
* parses a=framerate:<float number>
*/
static int sdp_decode_parse_a_frame (int arg,
char *lptr,
session_desc_t *sptr,
media_desc_t *mptr)
{
char *endptr;
if (mptr == NULL) {
return (-1);
}
mptr->framerate = strtod(lptr, &endptr);
if (endptr == lptr || endptr == NULL) return (-1);
ADV_SPACE(endptr);
if (*endptr != '\0') {
Rtsp_Printf( "Garbage at end of frame rate `%s\'\n", endptr);
return (-1);
}
mptr->framerate_present = TRUE;
return (0);
}
static int convert_npt (char *from, char *to, double *ret)
{
int decimal = FALSE;
double accum;
double mult;
*ret = 0.0;
mult = 0.0;
accum = 0.0;
while ((to == NULL && *from != '\0') || from < to) {
if (isdigit(*from)) {
if (decimal == FALSE) {
accum *= 10.0;
accum += (double)(*from )- (double)'0';
} else {
accum += (((double)(*from) - (double) '0') * mult);
mult /= 10.0;
}
} else if (*from == ':') {
accum *= 60.0;
*ret += accum;
accum = 0;
} else if (*from == '.') {
decimal = TRUE;
mult = .1;
} else if (strncmp(from,"beginning",strlen("beginning"))==0){
*ret=0;
return(TRUE);
} else {
Rtsp_Printf( "Illegal character in NPT string %c\n", *from);
return (FALSE);
}
from++;
}
*ret += accum;
return (TRUE);
}
static int convert_pts (char *from, char *to, double *ret)
{
int decimal = FALSE;
double accum;
double mult;
*ret = 0.0;
mult = 0.0;
accum = 0.0;
while ((to == NULL && *from != '\0') || from < to) {
if (isdigit(*from)) {
if (decimal == FALSE) {
accum *= 10.0;
accum += (double) *from - (double) '0';
} else {
accum += (((double) *from - (double) '0') * mult);
mult /= 10.0;
}
} else if (*from == ':') {
accum *= 60.0;
*ret += accum;
accum = 0;
} else if (*from == '.') {
decimal = TRUE;
mult = .1;
} else if (strncmp(from,"beginning",strlen("beginning"))==0){
*ret=0;
return(TRUE);
} else {
Rtsp_Printf( "Illegal character in NPT string %c\n", *from);
return (FALSE);
}
from++;
}
*ret += accum;
return (TRUE);
}
static int convert_smpte (char *from, char *to, uint16_t fps, double *ret)
{
int decimal = FALSE;
double accum;
double mult;
unsigned int colon;
*ret = 0.0;
mult = 0.0;
accum = 0.0;
colon = 0;
if (fps == 0) fps = 30;
while ((to == NULL && *from != '\0') || from < to) {
if (isdigit(*from)) {
if (decimal == FALSE) {
accum *= 10.0;
accum += ((double)*from - (double)'0');
} else {
accum += (((double) *from - (double) '0') * mult);
mult /= 10.0;
}
} else if (*from == ':') {
*ret += accum;
if (colon > 1)
*ret *= fps;
else
*ret *= 60.0;
accum = 0.0;
colon++;
} else if (*from == '.') {
decimal = TRUE;
mult = .1;
} else {
Rtsp_Printf( "Illegal character in SMPTE decode %c\n", *from);
return (FALSE);
}
from++;
}
*ret += accum;
if (colon <= 2) *ret *= fps;
return (TRUE);
}
static int sdp_decode_parse_a_range (int arg,
char *lptr,
session_desc_t *sptr,
media_desc_t *mptr)
{
char *dash;
char *second;
range_desc_t *rptr;
if (mptr == NULL) rptr = &sptr->session_range;
else rptr = &mptr->media_range;
if (rptr->have_range) return (-1);
if (strncmp(lptr, "npt", strlen("npt")) == 0) {
lptr += strlen("npt");
rptr->range_is_npt = TRUE;
} else if (strncmp(lptr, "smpte", strlen("smpte")) == 0) {
lptr += strlen("smpte");
rptr->range_is_npt = FALSE;
if (*lptr == '-') {
lptr++;
if (strncmp(lptr, "30-drop", strlen("30-drop")) == 0) {
rptr->range_smpte_fps = 0;
lptr += strlen("30-drop");
} else {
while (isdigit(*lptr)) {
rptr->range_smpte_fps *= 10;
rptr->range_smpte_fps += *lptr - '0';
lptr++;
}
}
} else {
rptr->range_smpte_fps = 0;
}
}else if(strncmp(lptr, "pts", strlen("pts")) == 0){
lptr += strlen("pts");
rptr->range_is_npt = FALSE;
rptr->range_is_pts = TRUE;
}else {
Rtsp_Printf( "range decode - unknown keyword %s\n", lptr);
return (-1);
}
ADV_SPACE(lptr);
if (*lptr != '=') {
Rtsp_Printf( "range decode - no =\n");
return (-1);
}
lptr++;
ADV_SPACE(lptr);
dash = strchr(lptr, '-');
if (dash == NULL) return (-1);
if (rptr->range_is_npt) {
if (convert_npt(lptr, dash, &rptr->range_start) == FALSE) {
Rtsp_Printf( "Couldn't decode range from npt %s\n", lptr);
return (-1);
}
} else {
if(rptr->range_is_pts)
{
if (convert_npt(lptr, dash, &rptr->range_start) == FALSE) {
Rtsp_Printf( "Couldn't decode range from pts %s\n", lptr);
return (-1);
}
}
else
{
if (convert_smpte(lptr,
dash,
rptr->range_smpte_fps,
&rptr->range_start) == FALSE) {
Rtsp_Printf( "Couldn't decode range from smpte %s\n", lptr);
return (-1);
}
}
}
second = dash + 1;
ADV_SPACE(second);
if (*second != '\0') {
if (rptr->range_is_npt) {
if(strncmp(second, "end", strlen("end")))
{
if (convert_npt(second, NULL, &rptr->range_end) == FALSE) {
Rtsp_Printf( "Couldn't decode range to npt %s\n", lptr);
return (-1);
}
}
else{
rptr->range_end_infinite = TRUE;
}
} else {
if(rptr->range_is_pts)
{
if(strncmp(second, "end", strlen("end")))
{
if (convert_pts(second, NULL, &rptr->range_end) == FALSE) {
Rtsp_Printf( "Couldn't decode range to pts %s\n", lptr);
return (-1);
}
}else{
rptr->range_end_infinite = TRUE;}
}
else
{
if (convert_smpte(second,
NULL,
rptr->range_smpte_fps,
&rptr->range_end) == FALSE) {
Rtsp_Printf( "Couldn't decode range to smpte %s\n", lptr);
return (-1);
}
}
}
} else {
rptr->range_end_infinite = TRUE;
}
rptr->have_range = TRUE;
return (0);
}
/*
* sdp_decode_parse_a_int()
* parses a=<name>:<uint>
*/
static int sdp_decode_parse_a_int (int arg,
char *orig_line,
session_desc_t *sptr,
media_desc_t *mptr)
{
uint32_t num;
num = 0;
if (!isdigit(*orig_line)) {
return (-1);
}
while (isdigit(*orig_line)) {
num *= 10;
num += *orig_line - '0';
orig_line++;
}
ADV_SPACE(orig_line);
if (*orig_line != '\0') {
Rtsp_Printf( "Garbage at end of integer %s\n", orig_line);
return(-1);
}
switch (arg) {
case 0:
if (mptr == NULL) return (-1);
mptr->ptime = num;
mptr->ptime_present = TRUE;
break;
case 1:
if (mptr == NULL) return (-1);
mptr->quality = num;
mptr->quality_present = TRUE;
break;
}
return (0);
}
/*
* check_value_list_or_user()
* This will compare string in lptr with items in list. If strncmp()
* matches, and the next value after the match in lptr is a space or \0,
* we return the index in list + 1.
* If no entrys are on the list, we'll strdup the value, and store in
* *uservalue
*/
static int check_value_list_or_user (char *lptr,
const char **list,
char **user_value)
{
uint32_t len;
int cnt;
cnt = 1;
while (*list != NULL) {
len = strlen(*list);
if (strncmp(lptr, *list, len) == 0) {
return (cnt);
}
cnt++;
list++;
}
*user_value = strdup(lptr);
return(cnt);
}
const char *type_values[] = {
"broadcast", /* CONFERENCE_TYPE_BROADCAST*/
"meeting", /* CONFERENCE_TYPE_MEETING */
"moderated", /* CONFERENCE_TYPE_MODERATED*/
"test", /* CONFERENCE_TYPE_TEST */
"H332", /* CONFERENCE_TYPE_H332 */
NULL /* CONFERENCE_TYPE_USER */
};
static const char *orient_values[] = {
"portrait", /* ORIENT_TYPE_PORTRAIT */
"landscape",/* ORIENT_TYPE_LANDSCAPE */
"seascape", /* ORIENT_TYPE_SEASCAPE */
NULL /* ORIENT_TYPE_USER */
};
/*
* sdp_decode_parse_a_str()
* parses a=<identifier>:<name>
* Will usually save the value of <name> in a field in the media_desc_t or
* session_desc_t.
*/
static int sdp_decode_parse_a_str (int arg,
char *lptr,
session_desc_t *sptr,
media_desc_t *mptr)
{
switch (arg) {
case 0: /* keywds*/
if (sptr->keywds != NULL) {
/* Rtsp_Printf( "2nd keywds statement\n");
*/
return (-1);
}
sptr->keywds =strdup(lptr);
break;
case 1: /* tool*/
if (sptr->tool != NULL) {
/* Rtsp_Printf( "2nd tool statement\n");
*/
return (-1);
}
sptr->tool = strdup(lptr);
break;
case 2: /* charset*/
if (sptr->charset != NULL) {
/* Rtsp_Printf( "2nd charset statement\n");
*/
return (-1);
}
sptr->charset = strdup(lptr);
break;
case 3: /* sdplang*/
if (mptr != NULL) {
if (mptr->sdplang != NULL) {
/* Rtsp_Printf( "2nd sdplang statement in media\n");
*/
return (-1);
}
mptr->sdplang = strdup(lptr);
} else {
if (sptr->sdplang != NULL) {
/* Rtsp_Printf( "2nd sdplang statement in session\n");
*/
return (-1);
}
sptr->sdplang = strdup(lptr);
}
break;
case 4: /* lang*/
if (mptr != NULL) {
if (mptr->lang != NULL) {
/* Rtsp_Printf( "2nd lang statement in media\n");
*/
return (-1);
}
mptr->lang = strdup(lptr);
} else {
if (sptr->lang != NULL) {
/* Rtsp_Printf( "2nd lang statement in media\n");
*/
return (-1);
}
sptr->lang =(char*) strdup(lptr);
}
break;
case 5: /* type*/
if (sptr->conf_type != 0) {
/* Rtsp_Printf( "2nd conftype statement\n");
*/
return (-1);
}
sptr->conf_type = check_value_list_or_user(lptr,
type_values,
&sptr->conf_type_user);
break;
case 6: /* orient*/
if (mptr == NULL || mptr->orient_type != 0) {
/* Rtsp_Printf( "2nd orient type statement\n");
*/
return (-1);
}
mptr->orient_type = check_value_list_or_user(lptr,
orient_values,
&mptr->orient_user_type);
break;
case 7: /* control*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -