📄 sdp_decode.c
字号:
sdp_debug(LOG_ERR, "Couldn't decode rtp clockrate %s", temp); return (-1); } b = 0; if (slash != NULL) { ADV_SPACE(slash); if (*slash == '/') { slash++; ADV_SPACE(slash); } if (isdigit(*slash)) { if (sscanf(slash, "%u", &b) != 1) { return -1; } } } } else { sdp_debug(LOG_CRIT, "a=rtpmap clock rate is missing."); sdp_debug(LOG_CRIT, "Most likely, you're decoding SDP from Apple's broadcaster"); sdp_debug(LOG_CRIT, "They initially misinterpreted RFC3016, but should fix it at some point"); sdp_debug(LOG_CRIT, "You may see audio/video at the wrong rate"); a = 90000; b = 0; } fptr->rtpmap_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; uint64_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 ((sep = strsep(&lptr, " \t."))) { if (*sep != '\0') { cat = 0; while (isdigit(*sep)) { cat *= 10; cat += *sep - '0'; sep++; } if (cat == 0) { break; } new = malloc(sizeof(category_list_t)); 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); } free(line); return (errret);}static int sdp_decode_parse_a_rtcp (int arg, char *lptr, session_desc_t *sptr, media_desc_t *mptr){ char *sep, *beg; uint32_t port; connect_desc_t *cptr; if (mptr == NULL) return (-1); if (mptr->rtcp_connect.used) return -1; port = 0; if (!isdigit(*lptr)) { sdp_debug(LOG_ERR, "Illegal port number in a=rtcp: %s", lptr); return (-1); } while (isdigit(*lptr)) { port *= 10; port += *lptr - '0'; lptr++; } ADV_SPACE(lptr); if (port > 65535) { sdp_debug(LOG_ERR, "Illegal port value %u in a=rtcp:", port); return (-1); } mptr->rtcp_port = port; mptr->rtcp_connect.used = true; if (*lptr == '\0') return 0; cptr = &mptr->rtcp_connect; // <address type> - should be IPV4 ADV_SPACE(lptr); sep = strsep(&lptr, SPACES); if (sep == NULL || lptr == NULL || strcasecmp(sep, "IN") != 0) { return 0; } ADV_SPACE(lptr); sep = strsep(&lptr, SPACES); if (sep == NULL || lptr == NULL) return 0; cptr->conn_type = strdup(sep); // Address - first look if we have a / - that indicates multicast, and a // ttl. ADV_SPACE(lptr); sep = strchr(lptr, '/'); if (sep == NULL) { // unicast address cptr->conn_addr = strdup(lptr); return (0); } // Okay - multicast address. Take address up to / (get rid of trailing // spaces) beg = lptr; lptr = sep + 1; sep--; while (isspace(*sep) && sep > beg) sep--; sep++; *sep = '\0'; cptr->conn_addr = strdup(beg); // Now grab the ttl ADV_SPACE(lptr); sep = strsep(&lptr, " \t/"); if (!isdigit(*sep)) { return 0; } if (sscanf(sep, "%u", &cptr->ttl) != 1) return -1; // And see if we have a number of ports if (lptr != NULL) { // we have a number of ports, as well ADV_SPACE(lptr); if (!isdigit(*lptr)) { return 0; } if (sscanf(lptr, "%u", &cptr->num_addr) != 1) return -1; } return 0;}/* * 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') { sdp_debug(LOG_ERR, "Garbage at end of frame rate `%s\'", 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 += *from - '0'; } else { accum += ((*from - '0') * mult); mult /= 10.0; } } else if (*from == ':') { accum *= 60.0; *ret += accum; accum = 0; } else if (*from == '.') { decimal = TRUE; mult = .1; } else { sdp_debug(LOG_ERR, "Illegal character in NPT string %c", *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 += (*from - '0'); } else { accum += ((*from - '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 { sdp_debug(LOG_ERR, "Illegal character in SMPTE decode %c", *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 (strncasecmp(lptr, "npt", strlen("npt")) == 0) { lptr += strlen("npt"); rptr->range_is_npt = TRUE; } else if (strncasecmp(lptr, "smpte", strlen("smpte")) == 0) { lptr += strlen("smpte"); rptr->range_is_npt = FALSE; if (*lptr == '-') { lptr++; if (strncasecmp(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 { sdp_debug(LOG_ERR, "range decode - unknown keyword %s", lptr); return (-1); } ADV_SPACE(lptr); if (*lptr != '=') { sdp_debug(LOG_ERR, "range decode - no ="); 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) { sdp_debug(LOG_ERR, "Couldn't decode range from npt %s", lptr); return (-1); } } else { if (convert_smpte(lptr, dash, rptr->range_smpte_fps, &rptr->range_start) == FALSE) { sdp_debug(LOG_ERR, "Couldn't decode range from smpte %s", lptr); return (-1); } } second = dash + 1; ADV_SPACE(second); if (*second != '\0') { if (rptr->range_is_npt) { if (convert_npt(second, NULL, &rptr->range_end) == FALSE) { sdp_debug(LOG_ERR, "Couldn't decode range to npt %s", lptr); return (-1); } } else { if (convert_smpte(second, NULL, rptr->range_smpte_fps, &rptr->range_end) == FALSE) { sdp_debug(LOG_ERR, "Couldn't decode range to smpte %s", 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') { sdp_debug(LOG_ERR, "Garbage at end of integer %s", 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 strncasecmp() * 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, const char **user_value){ uint32_t len; int cnt; cnt = 1; while (*list != NULL) { len = strlen(*list); if (strncasecmp(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) { sdp_debug(LOG_ERR, "2nd keywds statement"); return (-1); } sptr->keywds = strdup(lptr); break; case 1: // tool if (sptr->tool != NULL) { sdp_debug(LOG_ERR, "2nd tool statement"); return (-1); } sptr->tool = strdup(lptr); break; case 2: // charset if (sptr->charset != NULL) { sdp_debug(LOG_ERR, "2nd charset statement"); return (-1); } sptr->charset = strdup(lptr); break; case 3: // sdplang if (mptr != NULL) { if (mptr->sdplang != NULL) { sdp_debug(LOG_ERR, "2nd sdplang statement in media"); return (-1); } mptr->sdplang = strdup(lptr); } else { if (sptr->sdplang != NULL) { sdp_debug(LOG_ERR, "2nd sdplang statement in session"); return (-1); } sptr->sdplang = strdup(lptr); } break; case 4: // lang if (mptr != NULL) { if (mptr->lang != NULL) { sdp_debug(LOG_ERR, "2nd lang statement in media"); return (-1); } mptr->lang = strdup(lptr); } else { if (sptr->lang != NULL) { sdp_debug(LOG_ERR, "2nd lang statement in media"); return (-1); } sptr->lang = strdup(lptr); } break; case 5: // type if (sptr->conf_type != 0) { sdp_debug(LOG_ERR, "2nd conftype statement"); 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) { sdp_debug(LOG_ERR, "2nd orient type statement"); return (-1); } mptr->orient_type = check_value_list_or_user(lptr, orient_values, &mptr->orient_user_type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -