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

📄 rtsp.c

📁 krtsp
💻 C
字号:
/** Parse RTSP-specific header fields.*  This file is same as rtspd/rtsp.c except for the short form table.*/#include "sysdep.h"#include <stdlib.h>   /* atoi(), atof(), strtol() */#include <string.h>   /* strchr() */#include <stdio.h>    /* sscanf() */#include <time.h>     /* mktime() */#include <sys/time.h> /* gettimeofday() */#include <timegm.h>   /* timegm() */#include "afi.h"#include "rtsp.h"#include "shortform.h"#include "strdupn.h"/** RTSP_CSeq()* RTSP sequence number.*/int RTSP_CSeq(parser_t *P){  parser_header_t *h = RFC822_Header(P->headers, "CSeq");    return h ? atoi(RFC822_Attribute(h, 0, 0)) : -1;} /* RTSP_CSeq *//** RTSP_MaxSize()* RTSP MaxSize header. return (unsigned long) -1 if* absent.*/unsigned long RTSP_MaxSize(parser_t *P){  parser_header_t *h = RFC822_Header(P->headers, "MaxSize");    return h ? atol(RFC822_Attribute(h, 0, 0)) : -1;} /* RTSP_CSeq *//* * RTSP_Range() * Range: clock= npt=; time= * Return range description. Does not support SMPTE (yet). */rtsp_range_t RTSP_Range(parser_t *P){  parser_header_t *h = RFC822_Header(P->headers, "Range");    rtsp_range_t r;  char *dash;  char *v;  r.effective = -1.;  r.type      = -1;  r.begin     = -1.;  r.end       = -1.;  if (h) {    v = RFC822_Attribute(h, 0, "time");    if (v) r.effective = strtoutc(v);    if ((v = RFC822_Attribute(h, 0, 0))) {      if (!strncmp(v, "clock=", strlen("clock=")) ) {        r.type = R_clock;        r.begin = strtoutc(v + strlen("clock="));        if ((dash = strchr(v, '-'))) r.end = strtoutc(dash+1);      }      else if (!strncmp(v,"npt=", strlen("npt="))) {        r.type = R_npt;        r.begin = strtonpt(v + strlen("npt="));        if ((dash = strchr(v, '-'))) {          if (*(dash+1) == '-') {            r.end = -1.0; /* XXX to interoperate with quicktime */          }          else {             r.end = strtonpt(dash+1);            if ( r.end == 0 ) {              r.end = -1.0; /* to the end */            }          }        }      }      else if (!strncmp(v, "smpte=", strlen("smpte="))) {        r.type = R_smpte;      }      else {      }    }  }  if (r.effective < 0) {    struct timeval tv;    gettimeofday(&tv, 0);    r.effective = tv.tv_sec + tv.tv_usec / 1e6;  }  return r;} /* RTSP_Range *//* * RTSP_Scale():  * Scale: 5.1 * Return play rate description. */float RTSP_Scale(parser_t *p){  parser_header_t *h = RFC822_Header(p->headers, "Scale");  float f = 1.0;  if (h) {     f = atof(h->elements->value);  }  return f;} /* RTSP_Scale *//* * RTSP_Subject(): XXX there is no Subject: header defined * in RTSP RFC. This is a non-standard feature. * Subject: Any text... * Returns the subject string. */const char * RTSP_Subject(parser_t *p){  parser_header_t *h = RFC822_Header(p->headers, "Subject");  if (h) {     return h->elements->value;  }  else {    return "No subject in RTSP message";  }} /* RTSP_Scale *//* * RTSP_Speed(): * Speed: 5.1 * Return delivery rate. */float RTSP_Speed(parser_t *p){  parser_header_t *h = RFC822_Header(p->headers, "Speed");  float f = 1.0;  if (h) {     f = atof(h->elements->value);  }  return f;} /* RTSP_Scale *//* * RTSP_Session: * Session: some string ;timeout=T * Return session identifier. */rtsp_session_t RTSP_Session(parser_t *p){  parser_header_t *h = RFC822_Header(p->headers, "Session");  rtsp_session_t s = {0, 0};  char *v;  if (h) {    s.id = h->elements->value;     v = RFC822_Attribute(h, 0, "timeout");    if (v) s.timeout = atoi(v);  }  return s;} /* RTSP_Session *//** RTSP_Timestamp():* Timestamp: 38383.3 1.03*/rtsp_timestamp_t RTSP_Timestamp(parser_t *P){  parser_header_t *h = RFC822_Header(P->headers, "Timestamp");  rtsp_timestamp_t t = {0,0};  char *v;  if (h && (v = RFC822_Attribute(h, 0, 0))) {    sscanf(v, "%lf %lf", &t.timestamp, &t.delay);  }  return t;} /* RTSP_Timestamp *//* * RTSP_Transport():  * Transport: RTP/AVP;multicast;compressed;ttl=127;mode="PLAY" * Returns a transport description. */rtsp_transport_t RTSP_Transport(parser_t *p){  parser_header_t *h = RFC822_Header(p->headers, "Transport");  char *v;  rtsp_transport_t r;  char *method;  r.protocol           = P_RTP;  r.profile            = Pr_AVP;  r.port[0]            = 3458;  r.port[1]            = 3459;  r.client_port[0]     = r.port[0];  r.client_port[1]     = r.port[1];  r.server_port[0]     = r.port[0];  r.server_port[1]     = r.port[1];  r.ttl                = 0;  r.layers             = 1;  r.ssrc               = 0;  r.multicast          = B_FALSE;  r.interleaved        = 0;  r.compressed         = 0;  r.mode               = 0;  method = HTTP_Method(p);  if (method != NULL ) {    if (!strcmp(method,"RECORD")) r.mode = T_RECORD;     /*07/24/99 AM */    if (!strcmp(method,"PLAY")) r.mode = T_PLAY;  }  r.append             = 0;  r.destination4.s_addr = INADDR_ANY;  memset(&r.destination6, 0, sizeof(struct in6_addr));  r.af                 = AF_UNSPEC;     /* default to nothing for now */  r.transport          = T_UDP;  if (h) {#if 1    parser_parameter_t *p = NULL;    if ( (v = RFC822_Attribute(h,0,0))) {      if ((!strncasecmp(v, "rtp/avp/tcp", strlen("rtp/avp/tcp"))) ){        r.transport = T_TCP;        r.profile   = Pr_AVP;        r.protocol  = P_RTP;      }      else if ((!strncasecmp(v, "rtp/avp",strlen("rtp/avp"))) ){        r.transport = T_UDP;        r.profile   = Pr_AVP;        r.protocol  = P_RTP;      }      else {        r.transport = T_UDP; // default assumed to be UDP         r.profile   = Pr_AVP;        r.protocol  = P_RTP;      }                  RFC822_ParseHeader(v,0,NULL,HT_standard,&p);      v = RFC822_Attribute1(p, "port");          if (v) sscanf(v, "%u-%u", &r.port[0], &r.port[1]);      v = RFC822_Attribute1(p, "client_port");      if (v) {        sscanf(v, "%u-%u", &r.client_port[0], &r.client_port[1]);        r.client_port[1] = r.client_port[0] + 1; /* XXX remove this line */      }      v = RFC822_Attribute1(p, "server_port");      if (v) sscanf(v, "%u-%u", &r.server_port[0], &r.server_port[1]);      v = RFC822_Attribute1(p, "ssrc");      if (v) r.ssrc = strtol(v,NULL,16);      v = RFC822_Attribute1(p, "ttl");      if (v) r.ttl = atoi(v);      v = RFC822_Attribute1(p, "interleaved");      if (v) r.interleaved = atoi(v);      v = RFC822_Attribute1(p, "compressed");      if (v) r.compressed = B_TRUE;      v = RFC822_Attribute1(p, "destination");       if (v) {        struct sockaddr_storage sin;        memset(&sin, 0, sizeof(sin));        if (AFIGetAddrByName(&sin, v) == 0) {          r.af = sin.ss_family;          if (sin.ss_family == AF_INET) {            struct sockaddr_in *p4 = (struct sockaddr_in*)&sin;            r.destination4.s_addr = p4->sin_addr.s_addr;          }          else {            struct sockaddr_in6 *p6 = (struct sockaddr_in6*)&sin;            memcpy(&r.destination6, &p6->sin6_addr, sizeof(struct in6_addr));          }        }      }      v = RFC822_Attribute1(p, "multicast");      if (v) r.multicast = B_TRUE;      if ( (v = RFC822_Attribute1(p, "rtp/avp")) ){        r.transport = T_UDP;        r.profile   = Pr_AVP;        r.protocol  = P_RTP;      }      else if ( (v = RFC822_Attribute1(p, "rtp/avp/tcp")) ){        r.transport = T_TCP;        r.profile   = Pr_AVP;        r.protocol  = P_RTP;      }      else {        r.transport = T_UDP; // default assumed to be UDP         r.profile   = Pr_AVP;        r.protocol  = P_RTP;      }      v = RFC822_Attribute1(p, "mode");      if (v) {        if (!strcasecmp(v, "PLAY"))   r.mode |= T_PLAY;        if (!strcasecmp(v, "RECORD")) r.mode |= T_RECORD;      }      RFC822_ParameterFree(p);    }#else    /*    * Following lines are removed and replaced by above lines    */    v = RFC822_Attribute(h, 0, "port");    if (v) sscanf(v, "%u-%u", &r.port[0], &r.port[1]);    v = RFC822_Attribute(h, 0, "client_port");    if (v) sscanf(v, "%u-%u", &r.client_port[0], &r.client_port[1]);    v = RFC822_Attribute(h, 0, "server_port");    if (v) sscanf(v, "%u-%u", &r.server_port[0], &r.server_port[1]);    v = RFC822_Attribute(h, 0, "ssrc");    if (v) r.ssrc = strtol(v,NULL,16);    v = RFC822_Attribute(h, 0, "ttl");    if (v) r.ttl = atoi(v);    v = RFC822_Attribute(h, 0, "interleaved");    if (v) r.interleaved = atoi(v);    v = RFC822_Attribute(h, 0, "compressed");    if (v) r.compressed = B_TRUE;    /* XXX: change this part to use AFIGetAddrByName as defined     * in the #if 1 part above.    */    v = RFC822_Attribute(h, 0, "destination");     if (v) r.destination = host2ip(v);    v = RFC822_Attribute(h, 0, "multicast");    if (v) r.multicast = B_TRUE;    if ( (v = RFC822_Attribute(h, 0, "rtp/avp")) ){      r.transport = T_UDP;      r.profile   = Pr_AVP;      r.protocol  = P_RTP;    }    else if ( (v = RFC822_Attribute(h, 0, "rtp/avp/tcp")) ){      r.transport = T_TCP;      r.profile   = Pr_AVP;      r.protocol  = P_RTP;    }    else {      r.transport = T_UDP; // default assumed to be UDP       r.profile   = Pr_AVP;      r.protocol  = P_RTP;    }    v = RFC822_Attribute(h, 0, "mode");    if (v) {      if (strstr(v, "PLAY"))   r.mode |= T_PLAY;      if (strstr(v, "RECORD")) r.mode |= T_RECORD;    }#endif  }   free_valid(method);  return r;} /* RTSP_Transport *//** strtonpt()* 124.45 or 12:05:04.3* Parse an NPT timestamp.*/double strtonpt(char *npt){  int hh = 0, mm = 0, ss = 0;  int n;              /* number of elements */  char *decimal;  double t;           /* converted time */  if (strchr(npt, ':')) {    n = sscanf(npt, "%d:%d:%d", &hh, &mm, &ss);    t = hh*3600 + mm*60 + ss;        }  else {    n = sscanf(npt, "%d", &ss);    t = ss;  }  if ((decimal = strchr(npt, '.'))) {    t += atof(decimal);  }  return t;} /* strtonpt *//** strtosmpte()* hh:mm:ss.frame*/double strtosmpte(char *smpte){  return 0.;} /* strtosmpte *//** strtoutc()* yyyymmddThhmmss.fZ (e.g., 19961108T143720.25Z)*/double strtoutc(char *utc){  double t;  char *decimal;        /* position of decimal point */  struct tm tm;  memset(&tm, 0, sizeof(tm));  sscanf(utc, "%4d%2d%2dT%2d%2d%2d", &tm.tm_year, &tm.tm_mon,    &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);  tm.tm_year -= 1900;  /* tm_year is years since 1900 */  tm.tm_mon  -= 1;     /* tm_mon is [0,11]! */  t = timegm(&tm);  /* Add fractions of a second. */  if ((decimal = strchr(utc, '.'))) t += atof(decimal);  return t;} /* strtoutc *//** utctostr()* Convert time to UTC string format.*/void utctostr(double utc, char *buffer){  struct tm tm;  time_t clock = (time_t)utc;  gmtime_r(&clock, &tm);  sprintf(buffer, "%04d%02d%02dT%02d%02d%02dZ",    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,    tm.tm_min, tm.tm_sec);} /* utctostr *//** npttostr()* Convert time to NPT format (as decimal, not hh:mm:ss). */void npttostr(double npt, char *buffer){  sprintf(buffer, "%.4f", npt);} /* npttostr *//** smptetostr()* Convert time to SMPTE format.*/void smptetostr(double smpte, char *buffer){} /* smptetostr */

⌨️ 快捷键说明

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