mpeg4_sdp.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:7k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * mpeg4_sdp.c - utilities for handling SDP structures
  23.  */
  24. #include "systems.h"
  25. #include <sdp/sdp.h>
  26. #include "mpeg4_sdp.h"
  27. #define ADV_SPACE(a) {while (isspace(*(a)) && (*(a) != ''))(a)++;}
  28. #define TTYPE(a,b) {a, sizeof(a), b}
  29. #define FMTP_PARSE_FUNC(a) static char *(a) (char *ptr, 
  30.      fmtp_parse_t *fptr, 
  31.      lib_message_func_t message)
  32. static char *fmtp_advance_to_next (char *ptr)
  33. {
  34.   while (*ptr != '' && *ptr != ';') ptr++;
  35.   if (*ptr == ';') ptr++;
  36.   return (ptr);
  37. }
  38. static char *fmtp_parse_number (char *ptr, int *ret_value)
  39. {
  40.   long int value;
  41.   char *ret_ptr;
  42.   
  43.   value = strtol(ptr, &ret_ptr, 0);
  44.   if ((ret_ptr != NULL) &&
  45.       (*ret_ptr == ';' || *ret_ptr == '')) {
  46.     if (*ret_ptr == ';') ret_ptr++;
  47.     if (value > INT_MAX) value = INT_MAX;
  48.     if (value < INT_MIN) value = INT_MIN;
  49.     *ret_value = value;
  50.     return (ret_ptr);
  51.   }
  52.   return (NULL);
  53. }
  54. FMTP_PARSE_FUNC(fmtp_streamtype)
  55. {
  56.   char *ret;
  57.   ret = fmtp_parse_number(ptr, &fptr->stream_type);
  58.   if (ret == NULL) {
  59.     ret = fmtp_advance_to_next(ptr);
  60.   }
  61.   return (ret);
  62. }
  63. FMTP_PARSE_FUNC(fmtp_profile_level_id)
  64. {
  65.   char *ret;
  66.   ret = fmtp_parse_number(ptr, &fptr->profile_level_id);
  67.   if (ret == NULL) {
  68.     ret = fmtp_advance_to_next(ptr);
  69.   }
  70.   return (ret);
  71. }
  72. static unsigned char to_hex (char *ptr)
  73. {
  74.   if (isdigit(*ptr)) {
  75.     return (*ptr - '0');
  76.   }
  77.   return (tolower(*ptr) - 'a' + 10);
  78. }
  79. FMTP_PARSE_FUNC(fmtp_config)
  80. {
  81.   char *iptr;
  82.   uint32_t len;
  83.   unsigned char *bptr;
  84.   
  85.   iptr = ptr;
  86.   while (isxdigit(*iptr)) iptr++;
  87.   len = iptr - ptr;
  88.   if (len == 0 || len & 0x1 || !(*iptr == ';' || *iptr == '')) {
  89.     message(LOG_ERR, "mp4util", "Error in fmtp config statement");
  90.     return (fmtp_advance_to_next(ptr));
  91.   }
  92.   iptr = fptr->config_ascii = (char *)malloc(len + 1);
  93.   len /= 2;
  94.   bptr = fptr->config_binary = (uint8_t *)malloc(len);
  95.   fptr->config_binary_len = len;
  96.   
  97.   while (len > 0) {
  98.     *bptr++ = (to_hex(ptr) << 4) | (to_hex(ptr + 1));
  99.     *iptr++ = *ptr++;
  100.     *iptr++ = *ptr++;
  101.     len--;
  102.   }
  103.   *iptr = '';
  104.   if (*ptr == ';') ptr++;
  105.   return (ptr);
  106. }
  107. FMTP_PARSE_FUNC(fmtp_constant_size)
  108. {
  109.   char *ret;
  110.   ret = fmtp_parse_number(ptr, &fptr->constant_size);
  111.   if (ret == NULL) {
  112.     ret = fmtp_advance_to_next(ptr);
  113.   }
  114.   return (ret);
  115. }
  116. FMTP_PARSE_FUNC(fmtp_size_length)
  117. {
  118.   char *ret;
  119.   ret = fmtp_parse_number(ptr, &fptr->size_length);
  120.   if (ret == NULL) {
  121.     ret = fmtp_advance_to_next(ptr);
  122.   }
  123.   return (ret);
  124. }
  125. FMTP_PARSE_FUNC(fmtp_index_length)
  126. {
  127.   char *ret;
  128.   ret = fmtp_parse_number(ptr, &fptr->index_length);
  129.   if (ret == NULL) {
  130.     ret = fmtp_advance_to_next(ptr);
  131.   }
  132.   return (ret);
  133. }
  134. FMTP_PARSE_FUNC(fmtp_index_delta_length)
  135. {
  136.   char *ret;
  137.   ret = fmtp_parse_number(ptr, &fptr->index_delta_length);
  138.   if (ret == NULL) {
  139.     ret = fmtp_advance_to_next(ptr);
  140.   }
  141.   return (ret);
  142. }
  143. FMTP_PARSE_FUNC(fmtp_CTS_delta_length)
  144. {
  145.   char *ret;
  146.   ret = fmtp_parse_number(ptr, &fptr->CTS_delta_length);
  147.   if (ret == NULL) {
  148.     ret = fmtp_advance_to_next(ptr);
  149.   }
  150.   return (ret);
  151. }
  152. FMTP_PARSE_FUNC(fmtp_DTS_delta_length)
  153. {
  154.   char *ret;
  155.   ret = fmtp_parse_number(ptr, &fptr->DTS_delta_length);
  156.   if (ret == NULL) {
  157.     ret = fmtp_advance_to_next(ptr);
  158.   }
  159.   return (ret);
  160. }
  161. FMTP_PARSE_FUNC(fmtp_auxiliary_data_size_length)
  162. {
  163.   char *ret;
  164.   ret = fmtp_parse_number(ptr, &fptr->auxiliary_data_size_length);
  165.   if (ret == NULL) {
  166.     ret = fmtp_advance_to_next(ptr);
  167.   }
  168.   return (ret);
  169. }
  170. FMTP_PARSE_FUNC(fmtp_bitrate)
  171. {
  172.   char *ret;
  173.   ret = fmtp_parse_number(ptr, &fptr->bitrate);
  174.   if (ret == NULL) {
  175.     ret = fmtp_advance_to_next(ptr);
  176.   }
  177.   return (ret);
  178. }
  179. FMTP_PARSE_FUNC(fmtp_profile)
  180. {
  181.   char *ret;
  182.   ret = fmtp_parse_number(ptr, &fptr->profile);
  183.   if (ret == NULL) {
  184.     ret = fmtp_advance_to_next(ptr);
  185.   }
  186.   return (ret);
  187. }
  188. FMTP_PARSE_FUNC(fmtp_mode)
  189. {
  190.   return (fmtp_advance_to_next(ptr));
  191. }
  192. struct {
  193.   const char *name;
  194.   uint32_t namelen;
  195.   char *(*routine)(char *, fmtp_parse_t *, lib_message_func_t);
  196. } fmtp_types[] = 
  197. {
  198.   TTYPE("streamtype", fmtp_streamtype),
  199.   TTYPE("profile-level-id", fmtp_profile_level_id),
  200.   TTYPE("config", fmtp_config),
  201.   TTYPE("constantsize", fmtp_constant_size),
  202.   TTYPE("sizelength", fmtp_size_length),
  203.   TTYPE("indexlength", fmtp_index_length),
  204.   TTYPE("indexdeltalength", fmtp_index_delta_length),
  205.   TTYPE("ctsdeltalength", fmtp_CTS_delta_length),
  206.   TTYPE("dtsdeltalength", fmtp_DTS_delta_length),
  207.   TTYPE("auxiliarydatasizelength", fmtp_auxiliary_data_size_length),
  208.   TTYPE("bitrate", fmtp_bitrate),
  209.   TTYPE("profile", fmtp_profile),
  210.   TTYPE("mode", fmtp_mode),
  211.   {NULL, 0, NULL},
  212. }; 
  213. fmtp_parse_t *parse_fmtp_for_mpeg4 (char *optr, lib_message_func_t message)
  214. {
  215.   int ix;
  216.   char *bptr;
  217.   fmtp_parse_t *ptr;
  218.   bptr = optr;
  219.   if (bptr == NULL) 
  220.     return (NULL);
  221.   ptr = (fmtp_parse_t *)malloc(sizeof(fmtp_parse_t));
  222.   if (ptr == NULL)
  223.     return (NULL);
  224.   
  225.   ptr->config_binary = NULL;
  226.   ptr->config_ascii = NULL;
  227.   ptr->profile_level_id = -1;
  228.   ptr->constant_size = 0;
  229.   ptr->size_length = 0;
  230.   ptr->index_length = 0;   // default value...
  231.   ptr->index_delta_length = 0;
  232.   ptr->CTS_delta_length = 0;
  233.   ptr->DTS_delta_length = 0;
  234.   ptr->auxiliary_data_size_length = 0;
  235.   ptr->bitrate = -1;
  236.   ptr->profile = -1;
  237.   do {
  238.     ADV_SPACE(bptr);
  239.     for (ix = 0; fmtp_types[ix].name != NULL; ix++) {
  240.       if (strncasecmp(bptr, 
  241.       fmtp_types[ix].name, 
  242.       fmtp_types[ix].namelen - 1) == 0) {
  243. bptr += fmtp_types[ix].namelen - 1;
  244. ADV_SPACE(bptr);
  245. if (*bptr != '=') {
  246.   message(LOG_ERR, "mp4util", "No = in fmtp %s %s",
  247.   fmtp_types[ix].name,
  248.   optr);
  249.   bptr = fmtp_advance_to_next(bptr);
  250.   break;
  251. }
  252. bptr++;
  253. ADV_SPACE(bptr);
  254. bptr = (fmtp_types[ix].routine)(bptr, ptr, message);
  255. break;
  256.       }
  257.     }
  258.     if (fmtp_types[ix].name == NULL) {
  259.       message(LOG_ERR, "mp4util", "Illegal name in bptr - skipping %s", 
  260.       bptr);
  261.       bptr = fmtp_advance_to_next(bptr);
  262.     }
  263.   } while (bptr != NULL && *bptr != '');
  264.   if (bptr == NULL) {
  265.     free_fmtp_parse(ptr);
  266.     return (NULL);
  267.   }
  268.   return (ptr);
  269. }
  270. void free_fmtp_parse (fmtp_parse_t *ptr)
  271. {
  272.   if (ptr->config_binary != NULL) {
  273.     free(ptr->config_binary);
  274.     ptr->config_binary = NULL;
  275.   }
  276.   if (ptr->config_ascii != NULL) {
  277.     free(ptr->config_ascii);
  278.     ptr->config_ascii = NULL;
  279.   }
  280.   free(ptr);
  281. }
  282. /* end file player_sdp.c */