⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdp_decode.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 4 页
字号:
  slash = strchr(enc, '/');  
  if (slash == NULL) {
    sdp_debug(LOG_ERR, "Couldn't find / in rtpmap");
    return (-1);
  }

  *slash++ = '\0';
  temp = enc;
  while ((!(isspace(*temp))) && *temp != '\0') temp++;
  *temp = '\0';
  
  // enc points to encode name
  ADV_SPACE(slash);
  temp = strsep(&slash, " \t/");
  if (temp == NULL) {
    sdp_debug(LOG_ERR, "Can't find seperator after encode name in rtpmap");
    return (-1);
  }

  if (sscanf(temp, "%u", &a) == 0) {
    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)) {
      sscanf(slash, "%u", &b);
    }
  }
  
  fptr->rtpmap = malloc(sizeof(rtpmap_desc_t));
  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;
  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);
}

/*
 * 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,
				     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);
    break;
  case 7: // control
    if (mptr == NULL) {
      if (sptr->control_string != NULL) {
	sdp_debug(LOG_ERR, "2nd control statement in media");
	return (-1);
      }
      sptr->control_string = strdup(lptr);
    } else {
      if (mptr->control_string != NULL) {
	sdp_debug(LOG_ERR, "2nd control statement in session");
	return (-1);
      }
      mptr->control_string = strdup(lptr);
    }
    break;
  case 8:
    if (sptr->etag != NULL) {
      sdp_debug(LOG_ERR, "2nd etag statement");
      return (-1);
    }
    sptr->etag = strdup(lptr);
    break;
  }
  return (0);
}
	

/*
 * This structure provides the information needed by the parsing
 * engine in sdp_decode_parse_a.  This function processes lines of
 * the format a=<identifier>[:<options>].
 * name - <identifier>
 * len - sizeof(identifier) (saves on CPU time)
 * have_colon - if a colon is necessary
 * remove_spaces_after_colon - if colon is necessary, and we want
 *   to remove spaces before <option>.  Do not use this if other character
 *   sets may come into play.
 * parse_routine - routine to call if keyword matched.  Return 0 if successful-
 *   -1 will save the whole "a=..." string.
 * arg - value to pass to parse_routine
 */
static struct {
  char *name;
  uint32_t len;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -