Statistics
| Branch: | Revision:

grapes / src / Chunkiser / stream-rtp.h @ 54b02213

History | View | Annotate | Download (3.59 KB)

1
/*
2
 *  Copyright (c) 2014 Davide Kirchner
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6

    
7
/*
8
  This file contains utitilites that are shared between rtp chunkiser
9
  (input-stream-rtp.c) and dechunkiser (output-stream-rtp.c)
10
 */
11

    
12
#define RTP_STREAMS_NUM_MAX 10
13
#define RTP_UDP_PORTS_NUM_MAX (2 * RTP_STREAMS_NUM_MAX)
14

    
15
/*
16
  Given a config string that is either <port> or <port>:<port>,
17
  fills ports[0] (rtp port) and ports[1] (rtcp port) with integers.
18
  Returns 0 on success, nonzero on failure.
19
 */
20
static inline int port_pair_parse(const char *conf_str, int *ports) {
21
  char *ptr;
22
  int port;
23

    
24
  ptr = strchr(conf_str, ':');
25
  if (ptr == NULL) {
26
    if (sscanf(conf_str, "%d", &port) == EOF) {
27
      return 1;
28
    }
29
    //fprintf(stderr, "  Parsed single port: %u\n", port);
30
    // pedantic compliant with RFC 5330, section 11:
31
    if (port % 2 == 0) {  // even port: this is RTP, the next is RTCP
32
      ports[0] = port;
33
      ports[1] = port + 1;
34
    }
35
    else {  // odd port: this is RTCP, previous is RTP
36
      ports[1] = port;
37
      ports[0] = port - 1;
38
    }
39
  }
40
  else {
41
    if (sscanf(conf_str, "%d:%d", &ports[0], &ports[1]) == EOF) {
42
      return 1;
43
    }
44
    //fprintf(stderr, "  Parsed double ports %u:%u\n", ports[0], ports[1]);
45
  }
46

    
47
  return 0;
48
}
49

    
50
/*
51
  Parses ports configuration: fills ports array and returns the number
52
  of ports found. If any error occurrs, returns 0 (note that if no
53
  ports are specified, it IS an error).
54
  If `video_stream_id` is not NULL, upon return it will contain the index
55
  of the video stream.
56
  In case an error occurrs, 0 is returned and `error_str` pointed to a message
57
 */
58
static inline int rtp_ports_parse(const struct tag *cfg_tags,
59
                                  int ports[RTP_UDP_PORTS_NUM_MAX + 1],
60
                                  int *video_stream_id,
61
                                  const char **error_str) {
62
  const char *val;
63
  int i = 0;
64
  int j;
65
  const char *port_pair_failed = \
66
    "Wrong format for port input: should be <port> or <rtp_port>:<rtcp_port>";
67

    
68
  /* Ports defined with explicit stream numbers */
69
  for (j = 0; j < RTP_STREAMS_NUM_MAX; j++) {
70
    char tag[8];
71

    
72
    sprintf(tag, "stream%d", j);
73
    val = grapes_config_value_str(cfg_tags, tag);
74
    if (val != NULL) {
75
      if (port_pair_parse(val, &ports[i]) != 0) {
76
        *error_str = port_pair_failed;
77
        return 0;
78
      }
79
      i += 2;
80
      if (video_stream_id != NULL) {
81
        *video_stream_id = 0;
82
      }
83
    }
84
  }
85
  /* Ports defined with "audio", "video" */
86
  if (i == 0) {
87
    val = grapes_config_value_str(cfg_tags, "audio");
88
    if (val != NULL) {
89
      if (port_pair_parse(val, &ports[i]) != 0) {
90
        *error_str = port_pair_failed;
91
        return 0;
92
      }
93
      i += 2;
94
    }
95
    val = grapes_config_value_str(cfg_tags, "video");
96
    if (val != NULL) {
97
      if (port_pair_parse(val, &ports[i]) != 0) {
98
        *error_str = port_pair_failed;
99
        return 0;
100
      }
101
      if (video_stream_id != NULL) {
102
        *video_stream_id = i / 2;
103
      }
104
      i += 2;
105
    }
106
  }
107
  /* Ports defined with "base" */
108
  if (i == 0) {
109
    if (grapes_config_value_int(cfg_tags, "base", &ports[0])) {
110
      ports[1] = ports[0] + 1;
111
      ports[2] = ports[1] + 1;
112
      ports[3] = ports[2] + 1;
113
      if (video_stream_id != NULL) {
114
        *video_stream_id = 1;
115
      }
116
      i += 4;
117
    }
118
  }
119
  // No port can be negative
120
  for (j = 0; j < i; j ++) {
121
    if (ports[j] < 0) {
122
      //printf_log(ctx, 0, "Negative ports (like %i) are not allowed", ports[j]);
123
      *error_str = "Negative ports not allowed";
124
      return 0;
125
    }
126
  }
127

    
128
  if (i == 0) {
129
    *error_str = "No listening port specified";
130
    return 0;
131
  }
132

    
133
  return i;
134
}