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

📄 sdp_decode.c

📁 嵌入式系统中c程序实现了rtsp协议的基本内容
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -