real_sdpplin.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 2002-2003 the xine project
  3.  *
  4.  * This file is part of xine, a free video player.
  5.  *
  6.  * xine is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * xine is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  19.  *
  20.  * $Id: 64e043af5431f0fed08769a6b62781b0f166cb7a $
  21.  *
  22.  * sdp/sdpplin parser.
  23.  *
  24.  */
  25.  
  26. #include "real.h"
  27. #define BUFLEN 32000
  28. /*
  29.  * Decodes base64 strings (based upon b64 package)
  30.  */
  31. static char *b64_decode(const char *in, char *out, int *size) {
  32.   char dtable[256];              /* Encode / decode table */
  33.   int i,k;
  34.   unsigned int j;
  35.   for( i = 0; i < 256; i++ )
  36.     dtable[i] = 0x80;
  37.   for( i = 'A'; i <= 'Z'; i++ )
  38.     dtable[i] = 0 + (i - 'A');
  39.   for( i = 'a'; i <= 'z'; i++ )
  40.     dtable[i] = 26 + (i - 'a');
  41.   for( i = '0'; i <= '9'; i++ )
  42.     dtable[i] = 52 + (i - '0');
  43.   dtable['+'] = 62;
  44.   dtable['/'] = 63;
  45.   dtable['='] = 0;
  46.   k=0;
  47.   /*CONSTANTCONDITION*/
  48.   int in_len = strlen(in);
  49.   for (j=0; j < in_len; j+=4) {
  50.     char a[4], b[4];
  51.     for (i = 0; i < 4 && j + i < in_len; i++) {
  52.       int c = in[i+j];
  53.       if (dtable[c] & 0x80) {
  54.         printf("Illegal character '%c' in input.n", c);
  55.         exit(1);
  56.       }
  57.       a[i] = (char) c;
  58.       b[i] = (char) dtable[c];
  59.     }
  60.     //xine_buffer_ensure_size(out, k+3);
  61.     out[k++] = (b[0] << 2) | (b[1] >> 4);
  62.     out[k++] = (b[1] << 4) | (b[2] >> 2);
  63.     out[k++] = (b[2] << 6) | b[3];
  64.     i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
  65.     if (i < 3) {
  66.       out[k]=0;
  67.       *size=k;
  68.       return out;
  69.     }
  70.   }
  71.   out[k]=0;
  72.   *size=k;
  73.   return out;
  74. }
  75. static char *nl(char *data) {
  76.   char *nlptr = (data) ? strchr(data,'n') : NULL;
  77.   return (nlptr) ? nlptr + 1 : NULL;
  78. }
  79. static int filter(const char *in, const char *filter, char **out, size_t outlen) {
  80.   int flen=strlen(filter);
  81.   size_t len;
  82.   if (!in) return 0;
  83.   len = (strchr(in,'n')) ? (size_t)(strchr(in,'n')-in) : strlen(in);
  84.   if (!strncmp(in,filter,flen)) {
  85.     if(in[flen]=='"') flen++;
  86.     if(in[len-1]==13) len--;
  87.     if(in[len-1]=='"') len--;
  88.     if( len-flen+1 > outlen )
  89.     {
  90.         printf("Discarding end of string to avoid overflow");
  91.         len=outlen+flen-1;
  92.     }
  93.     memcpy(*out, in+flen, len-flen+1);
  94.     (*out)[len-flen]=0;
  95.     return len-flen;
  96.   }
  97.   return 0;
  98. }
  99. static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
  100.   sdpplin_stream_t *desc;
  101.   char* buf = NULL;
  102.   char* decoded = NULL;
  103.   int handled;
  104.   desc = calloc( 1, sizeof(sdpplin_stream_t) );
  105.   if( !desc )
  106.     return NULL;
  107.   buf = malloc( BUFLEN );
  108.   if( !buf )
  109.     goto error;
  110.   decoded = malloc( BUFLEN );
  111.   if( !decoded )
  112.     goto error;
  113.   if (filter(*data, "m=", &buf, BUFLEN)) {
  114.     desc->id = strdup(buf);
  115.   } else {
  116.     lprintf("sdpplin: no m= found.n");
  117.     goto error;
  118.   }
  119.   *data=nl(*data);
  120.   while (*data && **data && *data[0]!='m') {
  121.     handled=0;
  122.     if(filter(*data,"a=control:streamid=",&buf, BUFLEN)) {
  123.         /* This way negative values are mapped to unfeasibly high
  124.          * values, and will be discarded afterward
  125.          */
  126.         unsigned long tmp = strtoul(buf, NULL, 10);
  127.         if ( tmp > UINT16_MAX )
  128.             lprintf("stream id out of bound: %lun", tmp);
  129.         else
  130.             desc->stream_id=tmp;
  131.         handled=1;
  132.         *data=nl(*data);
  133.     }
  134.     if(filter(*data,"a=MaxBitRate:integer;",&buf, BUFLEN)) {
  135.       desc->max_bit_rate=atoi(buf);
  136.       if (!desc->avg_bit_rate)
  137.         desc->avg_bit_rate=desc->max_bit_rate;
  138.       handled=1;
  139.       *data=nl(*data);
  140.     }
  141.     if(filter(*data,"a=MaxPacketSize:integer;",&buf, BUFLEN)) {
  142.       desc->max_packet_size=atoi(buf);
  143.       if (!desc->avg_packet_size)
  144.         desc->avg_packet_size=desc->max_packet_size;
  145.       handled=1;
  146.       *data=nl(*data);
  147.     }
  148.     if(filter(*data,"a=StartTime:integer;",&buf, BUFLEN)) {
  149.       desc->start_time=atoi(buf);
  150.       handled=1;
  151.       *data=nl(*data);
  152.     }
  153.     if(filter(*data,"a=Preroll:integer;",&buf, BUFLEN)) {
  154.       desc->preroll=atoi(buf);
  155.       handled=1;
  156.       *data=nl(*data);
  157.     }
  158.     if(filter(*data,"a=length:npt=",&buf, BUFLEN)) {
  159.       desc->duration=(uint32_t)(atof(buf)*1000);
  160.       handled=1;
  161.       *data=nl(*data);
  162.     }
  163.     if(filter(*data,"a=StreamName:string;",&buf, BUFLEN)) {
  164.       desc->stream_name=strdup(buf);
  165.       desc->stream_name_size=strlen(desc->stream_name);
  166.       handled=1;
  167.       *data=nl(*data);
  168.     }
  169.     if(filter(*data,"a=mimetype:string;",&buf, BUFLEN)) {
  170.       desc->mime_type=strdup(buf);
  171.       desc->mime_type_size=strlen(desc->mime_type);
  172.       handled=1;
  173.       *data=nl(*data);
  174.     }
  175.     if(filter(*data,"a=OpaqueData:buffer;",&buf, BUFLEN)) {
  176.       decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
  177.       if ( decoded != NULL ) {
  178.           desc->mlti_data = malloc(desc->mlti_data_size);
  179.           memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
  180.           handled=1;
  181.           *data=nl(*data);
  182.           lprintf("mlti_data_size: %in", desc->mlti_data_size);
  183.       }
  184.     }
  185.     if(filter(*data,"a=ASMRuleBook:string;",&buf, BUFLEN)) {
  186.       desc->asm_rule_book=strdup(buf);
  187.       handled=1;
  188.       *data=nl(*data);
  189.     }
  190.     if(!handled) {
  191. #ifdef LOG
  192.       int len=strchr(*data,'n')-(*data);
  193.       memcpy(buf, *data, len+1);
  194.       buf[len]=0;
  195.       printf("libreal: sdpplin: not handled: '%s'n", buf);
  196. #endif
  197.       *data=nl(*data);
  198.     }
  199.   }
  200.   free( buf );
  201.   free( decoded) ;
  202.   return desc;
  203. error:
  204.   free( decoded );
  205.   free( desc );
  206.   free( buf );
  207.   return NULL;
  208. }
  209. sdpplin_t *sdpplin_parse(char *data)
  210. {
  211.   sdpplin_t*        desc;
  212.   sdpplin_stream_t* stream;
  213.   char*             buf;
  214.   char*             decoded;
  215.   int               handled;
  216.   int               len;
  217.   desc = calloc( 1, sizeof(sdpplin_t) );
  218.   if( !desc )
  219.     return NULL;
  220.   buf = malloc( BUFLEN );
  221.   if( !buf )
  222.   {
  223.     free( desc );
  224.     return NULL;
  225.   }
  226.   decoded = malloc( BUFLEN );
  227.   if( !decoded )
  228.   {
  229.     free( buf );
  230.     free( desc );
  231.     return NULL;
  232.   }
  233.   desc->stream = NULL;
  234.   while (data && *data) {
  235.     handled=0;
  236.     if (filter(data, "m=", &buf, BUFLEN)) {
  237.         if ( !desc->stream ) {
  238.             fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping.");
  239.             continue;
  240.         }
  241.         stream=sdpplin_parse_stream(&data);
  242.         lprintf("got data for stream id %un", stream->stream_id);
  243.         if ( stream->stream_id >= desc->stream_count )
  244.             lprintf("stream id %u is greater than stream count %un", stream->stream_id, desc->stream_count);
  245.         else
  246.             desc->stream[stream->stream_id]=stream;
  247.         continue;
  248.     }
  249.     if(filter(data,"a=Title:buffer;",&buf, BUFLEN)) {
  250.       decoded=b64_decode(buf, decoded, &len);
  251.   if ( decoded != NULL ) {
  252.           desc->title=strdup(decoded);
  253.           handled=1;
  254.           data=nl(data);
  255.       }
  256.     }
  257.     if(filter(data,"a=Author:buffer;",&buf, BUFLEN)) {
  258.       decoded=b64_decode(buf, decoded, &len);
  259.   if ( decoded != NULL ) {
  260.           desc->author=strdup(decoded);
  261.           handled=1;
  262.           data=nl(data);
  263.       }
  264.     }
  265.     if(filter(data,"a=Copyright:buffer;",&buf, BUFLEN)) {
  266.       decoded=b64_decode(buf, decoded, &len);
  267.   if ( decoded != NULL ) {
  268.           desc->copyright=strdup(decoded);
  269.           handled=1;
  270.           data=nl(data);
  271.       }
  272.     }
  273.     if(filter(data,"a=Abstract:buffer;",&buf, BUFLEN)) {
  274.       decoded=b64_decode(buf, decoded, &len);
  275.       if ( decoded != NULL ) {
  276.            desc->abstract=strdup(decoded);
  277.            handled=1;
  278.            data=nl(data);
  279.       }
  280.     }
  281.     if(filter(data,"a=StreamCount:integer;",&buf, BUFLEN)) {
  282.         /* This way negative values are mapped to unfeasibly high
  283.          * values, and will be discarded afterward
  284.          */
  285.         unsigned long tmp = strtoul(buf, NULL, 10);
  286.         if ( tmp > UINT16_MAX )
  287.             lprintf("stream count out of bound: %lun", tmp);
  288.         else
  289.             desc->stream_count = tmp;
  290.         desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
  291.         handled=1;
  292.         data=nl(data);
  293.     }
  294.     if(filter(data,"a=Flags:integer;",&buf, BUFLEN)) {
  295.       desc->flags=atoi(buf);
  296.       handled=1;
  297.       data=nl(data);
  298.     }
  299.     if(!handled) {
  300. #ifdef LOG
  301.       int len=strchr(data,'n')-data;
  302.       memcpy(buf, data, len+1);
  303.       buf[len]=0;
  304.       printf("libreal: sdpplin: not handled: '%s'n", buf);
  305. #endif
  306.       data=nl(data);
  307.     }
  308.   }
  309.   free( decoded );
  310.   free( buf );
  311.   return desc;
  312. }
  313. void sdpplin_free(sdpplin_t *description) {
  314.   int i;
  315.   if( !description ) return;
  316.   for( i=0; i<description->stream_count; i++ ) {
  317.     if( description->stream[i] ) {
  318.       free( description->stream[i]->id );
  319.       free( description->stream[i]->bandwidth );
  320.       free( description->stream[i]->range );
  321.       free( description->stream[i]->length );
  322.       free( description->stream[i]->rtpmap );
  323.       free( description->stream[i]->mimetype );
  324.       free( description->stream[i]->stream_name );
  325.       free( description->stream[i]->mime_type );
  326.       free( description->stream[i]->mlti_data );
  327.       free( description->stream[i]->rmff_flags );
  328.       free( description->stream[i]->asm_rule_book );
  329.       free( description->stream[i] );
  330.     }
  331.   }
  332.   if( description->stream_count )
  333.     free( description->stream );
  334.   free( description->owner );
  335.   free( description->session_name );
  336.   free( description->session_info );
  337.   free( description->uri );
  338.   free( description->email );
  339.   free( description->phone );
  340.   free( description->connection );
  341.   free( description->bandwidth );
  342.   free( description->title );
  343.   free( description->author );
  344.   free( description->copyright );
  345.   free( description->keywords );
  346.   free( description->asm_rule_book );
  347.   free( description->abstract );
  348.   free( description->range );
  349.   free( description );
  350. }