Statistics
| Branch: | Revision:

grapes / src / Tests / chunkiser_test.c @ f6e93568

History | View | Annotate | Download (6.51 KB)

1
/*
2
 *  Copyright (c) 2010 Csaba Kiraly
3
 *  Copyright (c) 2010 Luca Abeni
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7

    
8
#include <unistd.h>
9
#include <stdio.h>
10
#include <stdint.h>
11
#include <stdlib.h>
12
#include <sys/types.h>
13
#include <sys/time.h>
14

    
15
#include "chunk.h"
16
#include "chunkiser.h"
17
#include "net_helper.h"
18

    
19
static char out_opts[1024];
20
static char *out_ptr = out_opts;
21
static char in_opts[1024];
22
static char *in_ptr = in_opts;
23
static int udp_port;
24
static int out_udp_port;
25

    
26
static int cycle;
27
static struct timeval tnext;
28

    
29
static void help(const char *name)
30
{
31
  fprintf(stderr, "Usage: %s [options] <input> <output>\n", name);
32
  fprintf(stderr, "options: t:u:f:rRdlavVUT\n");
33
  fprintf(stderr, "\t -u <port>: use the UDP chunkiser (on <port>) for input\n");
34
  fprintf(stderr, "\t -P <port>: use the UDP chunkiser (on <port>) for output\n");
35
  fprintf(stderr, "\t -f <fmt>: use the <fmt> format for ouptut (libav-based)\n");
36
  fprintf(stderr, "\t -r: use RAW output\n");
37
  fprintf(stderr, "\t -R: use RAW output, removing the libav payload header\n");
38
  fprintf(stderr, "\t -d: use the dummy chunkiser\n");
39
  fprintf(stderr, "\t -l: loop\n");
40
  fprintf(stderr, "\t -a: audio-only in the libav ouptut\n");
41
  fprintf(stderr, "\t -v: video-only in the libav output\n");
42
  fprintf(stderr, "\t -V: audio/video in the libav output\n");
43
  fprintf(stderr, "\t -U: use RAW output, removing the UDP payload header\n");
44
  fprintf(stderr, "\t -T: use RAW output, removing the RTP payload heade\n");
45
  fprintf(stderr, "\t -I <config>: specify the chunkiser config\n");
46
  fprintf(stderr, "\t -O <config>: specify the dechunkiser config\n");
47
}
48

    
49
static char *addopt(char *opts, char *opts_ptr, const char *tag, const char *value)
50
{
51
  if (opts_ptr != opts) {
52
    *opts_ptr++ = ',';
53
  }
54
  opts_ptr += sprintf(opts_ptr, "%s=%s", tag, value);
55
  return opts_ptr;
56
}
57

    
58
static int cmdline_parse(int argc, char *argv[])
59
{
60
  int o;
61

    
62
  while ((o = getopt(argc, argv, "tlP:u:f:rRdlavVUTO:I:")) != -1) {
63
    char port[8];
64

    
65
    switch(o) {
66
      case 'l':
67
        in_ptr = addopt(in_opts, in_ptr, "loop", "1");
68
        break;
69
      case 'P':
70
        if (out_udp_port == 0) {
71
          out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "udp");
72
        }
73
        sprintf(port, "port%d", out_udp_port);
74
        out_udp_port++;
75
        out_ptr = addopt(out_opts, out_ptr, port, optarg);
76
        break;
77
      case 't':
78
        in_ptr = addopt(in_opts, in_ptr, "chunkiser", "ts");
79
        break;
80
      case 'u':
81
        if (udp_port == 0) {
82
          in_ptr = addopt(in_opts, in_ptr, "chunkiser", "udp");
83
        }
84
        sprintf(port, "port%d", udp_port);
85
        udp_port++;
86
        in_ptr = addopt(in_opts, in_ptr, port, optarg);
87
        break;
88
      case 'f':
89
        out_ptr = addopt(out_opts, out_ptr, "format", optarg);
90
        break;
91
      case 'r':
92
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "raw");
93
        break;
94
      case 'R':
95
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "raw");
96
        out_ptr = addopt(out_opts, out_ptr, "payload", "avf");
97
        break;
98
      case 'U':
99
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "raw");
100
        out_ptr = addopt(out_opts, out_ptr, "payload", "udp");
101
        break;
102
      case 'T':
103
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "raw");
104
        out_ptr = addopt(out_opts, out_ptr, "payload", "rtp");
105
        break;
106
      case 'd':
107
        in_ptr = addopt(in_opts, in_ptr, "chunkiser", "dummy");
108
        break;
109
      case 'a':
110
        in_ptr = addopt(in_opts, in_ptr, "chunkiser", "avf");
111
        in_ptr = addopt(in_opts, in_ptr, "media", "audio");
112
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "avf");
113
        out_ptr = addopt(out_opts, out_ptr, "media", "audio");
114
        break;
115
      case 'v':
116
        in_ptr = addopt(in_opts, in_ptr, "chunkiser", "avf");
117
        in_ptr = addopt(in_opts, in_ptr, "media", "video");
118
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "avf");
119
        out_ptr = addopt(out_opts, out_ptr, "media", "video");
120
        break;
121
      case 'V':
122
        in_ptr = addopt(in_opts, in_ptr, "chunkiser", "avf");
123
        in_ptr = addopt(in_opts, in_ptr, "media", "av");
124
        out_ptr = addopt(out_opts, out_ptr, "dechunkiser", "avf");
125
        out_ptr = addopt(out_opts, out_ptr, "media", "av");
126
        break;
127
      case 'O':
128
        out_ptr += sprintf(out_ptr, "%s", optarg);
129
        break;
130
      case 'I':
131
        in_ptr += sprintf(in_ptr, "%s", optarg);
132
        break;
133
      default:
134
        fprintf(stderr, "Error: unknown option %c\n", o);
135

    
136
        exit(-1);
137
    }
138
  }
139

    
140
  return optind - 1;
141
}
142

    
143
void tout_init(struct timeval *tv)
144
{
145
  struct timeval tnow;
146

    
147
  gettimeofday(&tnow, NULL);
148
  if(timercmp(&tnow, &tnext, <)) {
149
    timersub(&tnext, &tnow, tv);
150
  } else {
151
    *tv = (struct timeval){0, 0};
152
  }
153
}
154

    
155
static void in_wait(const int *fd, uint64_t ts)
156
{
157
  int my_fd[10], *pfd;
158
  int i = 0;
159
  struct timeval tv, *ptv, tadd;
160
  static struct timeval tfirst;
161
  static uint64_t tsfirst;
162
  
163
  if (ts == 0) {
164
    ptv = NULL;
165
  } else {
166
    if (tfirst.tv_sec == 0) {
167
      gettimeofday(&tfirst, NULL);
168
      tsfirst = ts;
169
    }
170
printf("Sleep %llu\n", ts - tsfirst + cycle);
171
    tadd.tv_sec = (ts - tsfirst + cycle) / 1000000;
172
    tadd.tv_usec = (ts - tsfirst + cycle) % 1000000;
173
    timeradd(&tfirst, &tadd, &tnext);
174
    tout_init(&tv);
175
    ptv = &tv;
176
  }
177
  if (fd) {
178
    while(fd[i] != -1) {
179
      my_fd[i] = fd[i];
180
      i++;
181
    }
182
    pfd = my_fd;
183
  } else {
184
    pfd = NULL;
185
  }
186
  my_fd[i] = -1;
187

    
188
  wait4data(NULL, ptv, pfd);
189
}
190

    
191
int main(int argc, char *argv[])
192
{
193
  int period, done, id;
194
  struct input_stream *input;
195
  struct output_stream *output;
196
  const int *in_fds;
197
  unsigned long long int ts;
198

    
199
  if (argc < 3) {
200
    help(argv[0]);
201

    
202
    return -1;
203
  }
204
  argv += cmdline_parse(argc, argv);
205
  input = input_stream_open(argv[1], &period, in_opts);
206
  if (input == NULL) {
207
    fprintf(stderr, "Cannot open input %s\n", argv[1]);
208

    
209
    return -1;
210
  }
211
  if (period == 0) {
212
    in_fds = input_get_fds(input);
213
  } else {
214
    in_fds = NULL;
215
    cycle = period;
216
  }
217
  output = out_stream_init(argv[2], out_opts);
218
  if (output == NULL) {
219
    fprintf(stderr, "Cannot open output %s\n", argv[2]);
220

    
221
    return -1;
222
  }
223

    
224
  ts = 1;
225
  done = 0; id = 0;
226
  while(!done) {
227
    int res;
228
    struct chunk c;
229

    
230
    in_wait(in_fds, ts);
231
    c.id = id;
232
    res = chunkise(input, &c);
233
    if (res > 0) {
234
      fprintf(stderr,"chunk %d: %d %llu\n", id++, c.size, c.timestamp);
235
      chunk_write(output, &c);
236
    } else if (res < 0) {
237
      done = 1;
238
    }
239
    ts = c.timestamp;
240
    free(c.data);
241
  }
242
  input_stream_close(input);
243
  out_stream_close(output);
244

    
245
  return 0;
246
}