FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/sbgdec.c
Date: 2024-04-23 16:28:37
Exec Total Coverage
Lines: 246 864 28.5%
Functions: 27 48 56.2%
Branches: 147 640 23.0%

Line Branch Exec Source
1 /*
2 * SBG (SBaGen) file format decoder
3 * Copyright (c) 2011 Nicolas George
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #include "libavutil/bprint.h"
26 #include "libavutil/channel_layout.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/log.h"
29 #include "libavutil/mem.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/time_internal.h"
32 #include "avformat.h"
33 #include "demux.h"
34 #include "internal.h"
35
36 #define SBG_SCALE (1 << 16)
37 #define DAY (24 * 60 * 60)
38 #define DAY_TS ((int64_t)DAY * AV_TIME_BASE)
39
40 struct sbg_demuxer {
41 AVClass *class;
42 int sample_rate;
43 int frame_size;
44 int max_file_size;
45 };
46
47 struct sbg_string {
48 char *s;
49 char *e;
50 };
51
52 enum sbg_fade_type {
53 SBG_FADE_SILENCE = 0,
54 SBG_FADE_SAME = 1,
55 SBG_FADE_ADAPT = 3,
56 };
57
58 struct sbg_fade {
59 int8_t in, out, slide;
60 };
61
62 enum sbg_synth_type {
63 SBG_TYPE_NONE,
64 SBG_TYPE_SINE,
65 SBG_TYPE_NOISE,
66 SBG_TYPE_BELL,
67 SBG_TYPE_MIX,
68 SBG_TYPE_SPIN,
69 };
70
71 /* bell: freq constant, ampl decreases exponentially, can be approx lin */
72
73 struct sbg_timestamp {
74 int64_t t;
75 char type; /* 0 for relative, 'N' for now, 'T' for absolute */
76 };
77
78 struct sbg_script_definition {
79 char *name;
80 int name_len;
81 int elements, nb_elements;
82 char type; /* 'S' or 'B' */
83 };
84
85 struct sbg_script_synth {
86 int carrier;
87 int beat;
88 int vol;
89 enum sbg_synth_type type;
90 struct {
91 int l, r;
92 } ref;
93 };
94
95 struct sbg_script_tseq {
96 struct sbg_timestamp ts;
97 char *name;
98 int name_len;
99 int lock;
100 struct sbg_fade fade;
101 };
102
103 struct sbg_script_event {
104 int64_t ts;
105 int64_t ts_int, ts_trans, ts_next;
106 int elements, nb_elements;
107 struct sbg_fade fade;
108 };
109
110 struct sbg_script {
111 struct sbg_script_definition *def;
112 struct sbg_script_synth *synth;
113 struct sbg_script_tseq *tseq;
114 struct sbg_script_tseq *block_tseq;
115 struct sbg_script_event *events;
116 int nb_def;
117 int nb_tseq;
118 int nb_events;
119 int nb_synth;
120 int64_t start_ts;
121 int64_t end_ts;
122 int64_t opt_fade_time;
123 int64_t opt_duration;
124 char *opt_mix;
125 int sample_rate;
126 uint8_t opt_start_at_first;
127 uint8_t opt_end_at_last;
128 };
129
130 struct sbg_parser {
131 void *log;
132 char *script, *end;
133 char *cursor;
134 struct sbg_script scs;
135 struct sbg_timestamp current_time;
136 int nb_block_tseq;
137 int nb_def_max, nb_synth_max, nb_tseq_max, nb_block_tseq_max;
138 int line_no;
139 char err_msg[128];
140 };
141
142 enum ws_interval_type {
143 WS_SINE = MKTAG('S','I','N','E'),
144 WS_NOISE = MKTAG('N','O','I','S'),
145 };
146
147 struct ws_interval {
148 int64_t ts1, ts2;
149 enum ws_interval_type type;
150 uint32_t channels;
151 int32_t f1, f2;
152 int32_t a1, a2;
153 uint32_t phi;
154 };
155
156 struct ws_intervals {
157 struct ws_interval *inter;
158 int nb_inter;
159 int max_inter;
160 };
161
162 5 static void *alloc_array_elem(void **array, size_t elsize,
163 int *size, int *max_size)
164 {
165 void *ret;
166
167
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (*size == *max_size) {
168 5 int m = FFMAX(32, FFMIN(*max_size, INT_MAX / 2) * 2);
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (*size >= m)
170 return NULL;
171 5 *array = av_realloc_f(*array, m, elsize);
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!*array)
173 return NULL;
174 5 *max_size = m;
175 }
176 5 ret = (char *)*array + elsize * *size;
177 5 memset(ret, 0, elsize);
178 5 (*size)++;
179 5 return ret;
180 }
181
182 7125 static int str_to_time(const char *str, int64_t *rtime)
183 {
184 7125 const char *cur = str;
185 char *end;
186 int hours, minutes;
187 7125 double seconds = 0;
188 7125 int64_t ts = 0;
189
190
4/4
✓ Branch 0 taken 1850 times.
✓ Branch 1 taken 5275 times.
✓ Branch 2 taken 1787 times.
✓ Branch 3 taken 63 times.
7125 if (*cur < '0' || *cur > '9')
191 7062 return 0;
192 63 hours = strtol(cur, &end, 10);
193
5/8
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 59 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
63 if (end == cur || *end != ':' || end[1] < '0' || end[1] > '9')
194 59 return 0;
195 4 cur = end + 1;
196 4 minutes = strtol(cur, &end, 10);
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (end == cur)
198 return 0;
199 4 cur = end;
200
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (*end == ':'){
201 4 seconds = strtod(cur + 1, &end);
202
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (end > cur + 1)
203 4 cur = end;
204 4 ts = av_clipd(seconds * AV_TIME_BASE, INT64_MIN/2, INT64_MAX/2);
205 }
206 4 *rtime = av_sat_add64((hours * 3600LL + minutes * 60LL) * AV_TIME_BASE, ts);
207 4 return cur - str;
208 }
209
210 7269 static inline int is_space(char c)
211 {
212
6/6
✓ Branch 0 taken 7262 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7260 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7259 times.
7269 return c == ' ' || c == '\t' || c == '\r';
213 }
214
215 static inline int scale_double(void *log, double d, double m, int *r)
216 {
217 m *= d * SBG_SCALE;
218 if (m < INT_MIN || m >= INT_MAX) {
219 if (log)
220 av_log(log, AV_LOG_ERROR, "%g is too large\n", d);
221 return AVERROR(EDOM);
222 }
223 *r = m;
224 return 0;
225 }
226
227 7252 static int lex_space(struct sbg_parser *p)
228 {
229 7252 char *c = p->cursor;
230
231
3/4
✓ Branch 0 taken 7261 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 7252 times.
7261 while (p->cursor < p->end && is_space(*p->cursor))
232 9 p->cursor++;
233 7252 return p->cursor > c;
234 }
235
236 8939 static int lex_char(struct sbg_parser *p, char c)
237 {
238
3/4
✓ Branch 0 taken 8939 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 8926 times.
8939 int r = p->cursor < p->end && *p->cursor == c;
239
240 8939 p->cursor += r;
241 8939 return r;
242 }
243
244 4 static int lex_double(struct sbg_parser *p, double *r)
245 {
246 double d;
247 char *end;
248
249
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
4 if (p->cursor == p->end || is_space(*p->cursor) || *p->cursor == '\n')
250 return 0;
251 4 d = strtod(p->cursor, &end);
252
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (end > p->cursor) {
253 2 *r = d;
254 2 p->cursor = end;
255 2 return 1;
256 }
257 2 return 0;
258 }
259
260 7134 static int lex_fixed(struct sbg_parser *p, const char *t, int l)
261 {
262
2/4
✓ Branch 0 taken 7134 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7134 times.
✗ Branch 3 not taken.
7134 if (p->end - p->cursor < l || memcmp(p->cursor, t, l))
263 7134 return 0;
264 p->cursor += l;
265 return 1;
266 }
267
268 14349 static int lex_line_end(struct sbg_parser *p)
269 {
270
3/4
✓ Branch 0 taken 14349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103 times.
✓ Branch 3 taken 14246 times.
14349 if (p->cursor < p->end && *p->cursor == '#') {
271 103 p->cursor++;
272
3/4
✓ Branch 0 taken 11220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11117 times.
✓ Branch 3 taken 103 times.
11220 while (p->cursor < p->end && *p->cursor != '\n')
273 11117 p->cursor++;
274 }
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14349 times.
14349 if (p->cursor == p->end)
276 /* simulate final LF for files lacking it */
277 return 1;
278
2/2
✓ Branch 0 taken 14243 times.
✓ Branch 1 taken 106 times.
14349 if (*p->cursor != '\n')
279 14243 return 0;
280 106 p->cursor++;
281 106 p->line_no++;
282 106 lex_space(p);
283 106 return 1;
284 }
285
286 1 static int lex_wsword(struct sbg_parser *p, struct sbg_string *rs)
287 {
288 1 char *s = p->cursor, *c = s;
289
290
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (s == p->end || *s == '\n')
291 return 0;
292
4/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
4 while (c < p->end && *c != '\n' && !is_space(*c))
293 3 c++;
294 1 rs->s = s;
295 1 rs->e = p->cursor = c;
296 1 lex_space(p);
297 1 return 1;
298 }
299
300 7128 static int lex_name(struct sbg_parser *p, struct sbg_string *rs)
301 {
302 7128 char *s = p->cursor, *c = s;
303
304
9/10
✓ Branch 0 taken 14224 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1041 times.
✓ Branch 3 taken 13183 times.
✓ Branch 4 taken 991 times.
✓ Branch 5 taken 50 times.
✓ Branch 6 taken 5918 times.
✓ Branch 7 taken 7315 times.
✓ Branch 8 taken 5814 times.
✓ Branch 9 taken 104 times.
14224 while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
305
8/8
✓ Branch 0 taken 515 times.
✓ Branch 1 taken 6904 times.
✓ Branch 2 taken 248 times.
✓ Branch 3 taken 267 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 7143 times.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 7128 times.
7419 || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-'))
306 7096 c++;
307
2/2
✓ Branch 0 taken 5325 times.
✓ Branch 1 taken 1803 times.
7128 if (c == s)
308 5325 return 0;
309 1803 rs->s = s;
310 1803 rs->e = p->cursor = c;
311 1803 return 1;
312 }
313
314 7125 static int lex_time(struct sbg_parser *p, int64_t *rt)
315 {
316 7125 int r = str_to_time(p->cursor, rt);
317 7125 p->cursor += r;
318 7125 return r > 0;
319 }
320
321 #define FORWARD_ERROR(c) \
322 do { \
323 int errcode = c; \
324 if (errcode <= 0) \
325 return errcode ? errcode : AVERROR_INVALIDDATA; \
326 } while (0)
327
328 static int parse_immediate(struct sbg_parser *p)
329 {
330 snprintf(p->err_msg, sizeof(p->err_msg),
331 "immediate sequences not yet implemented");
332 return AVERROR_PATCHWELCOME;
333 }
334
335 static int parse_preprogrammed(struct sbg_parser *p)
336 {
337 snprintf(p->err_msg, sizeof(p->err_msg),
338 "preprogrammed sequences not yet implemented");
339 return AVERROR_PATCHWELCOME;
340 }
341
342 static int parse_optarg(struct sbg_parser *p, char o, struct sbg_string *r)
343 {
344 if (!lex_wsword(p, r)) {
345 snprintf(p->err_msg, sizeof(p->err_msg),
346 "option '%c' requires an argument", o);
347 return AVERROR_INVALIDDATA;
348 }
349 return 1;
350 }
351
352 7230 static int parse_options(struct sbg_parser *p)
353 {
354 struct sbg_string ostr, oarg;
355 7230 char mode = 0;
356 int r;
357 char *tptr;
358 double v;
359
360
3/4
✓ Branch 0 taken 7230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7229 times.
✓ Branch 3 taken 1 times.
7230 if (p->cursor == p->end || *p->cursor != '-')
361 7229 return 0;
362
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 while (lex_char(p, '-') && lex_wsword(p, &ostr)) {
363
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (; ostr.s < ostr.e; ostr.s++) {
364 1 char opt = *ostr.s;
365
1/11
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
1 switch (opt) {
366 case 'S':
367 p->scs.opt_start_at_first = 1;
368 break;
369 case 'E':
370 p->scs.opt_end_at_last = 1;
371 break;
372 case 'i':
373 mode = 'i';
374 break;
375 case 'p':
376 mode = 'p';
377 break;
378 case 'F':
379 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
380 v = strtod(oarg.s, &tptr);
381 if (oarg.e != tptr) {
382 snprintf(p->err_msg, sizeof(p->err_msg),
383 "syntax error for option -F");
384 return AVERROR_INVALIDDATA;
385 }
386 p->scs.opt_fade_time = v * AV_TIME_BASE / 1000;
387 break;
388 case 'L':
389 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
390 r = str_to_time(oarg.s, &p->scs.opt_duration);
391 if (oarg.e != oarg.s + r || p->scs.opt_duration < 0) {
392 snprintf(p->err_msg, sizeof(p->err_msg),
393 "syntax error for option -L");
394 return AVERROR_INVALIDDATA;
395 }
396 break;
397 case 'T':
398 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
399 r = str_to_time(oarg.s, &p->scs.start_ts);
400 if (oarg.e != oarg.s + r) {
401 snprintf(p->err_msg, sizeof(p->err_msg),
402 "syntax error for option -T");
403 return AVERROR_INVALIDDATA;
404 }
405 break;
406 case 'm':
407 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
408 tptr = av_malloc(oarg.e - oarg.s + 1);
409 if (!tptr)
410 return AVERROR(ENOMEM);
411 memcpy(tptr, oarg.s, oarg.e - oarg.s);
412 tptr[oarg.e - oarg.s] = 0;
413 av_free(p->scs.opt_mix);
414 p->scs.opt_mix = tptr;
415 break;
416 case 'q':
417 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
418 v = strtod(oarg.s, &tptr);
419 if (oarg.e != tptr) {
420 snprintf(p->err_msg, sizeof(p->err_msg),
421 "syntax error for option -q");
422 return AVERROR_INVALIDDATA;
423 }
424 if (v != 1) {
425 snprintf(p->err_msg, sizeof(p->err_msg),
426 "speed factor other than 1 not supported");
427 return AVERROR_PATCHWELCOME;
428 }
429 break;
430 case 'r':
431 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
432 r = strtol(oarg.s, &tptr, 10);
433 if (oarg.e != tptr) {
434 snprintf(p->err_msg, sizeof(p->err_msg),
435 "syntax error for option -r");
436 return AVERROR_INVALIDDATA;
437 }
438 if (r < 40) {
439 snprintf(p->err_msg, sizeof(p->err_msg),
440 "invalid sample rate");
441 return AVERROR_PATCHWELCOME;
442 }
443 p->scs.sample_rate = r;
444 break;
445 1 default:
446 1 snprintf(p->err_msg, sizeof(p->err_msg),
447 1 "unknown option: '%c'", *ostr.s);
448 1 return AVERROR_INVALIDDATA;
449 }
450 }
451 }
452 switch (mode) {
453 case 'i':
454 return parse_immediate(p);
455 case 'p':
456 return parse_preprogrammed(p);
457 case 0:
458 if (!lex_line_end(p))
459 return AVERROR_INVALIDDATA;
460 return 1;
461 }
462 return AVERROR_BUG;
463 }
464
465 7123 static int parse_timestamp(struct sbg_parser *p,
466 struct sbg_timestamp *rts, int64_t *rrel)
467 {
468 7123 int64_t abs = 0, rel = 0, dt;
469 7123 char type = 0;
470 int r;
471
472
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7123 times.
7123 if (lex_fixed(p, "NOW", 3)) {
473 type = 'N';
474 r = 1;
475 } else {
476 7123 r = lex_time(p, &abs);
477
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7119 times.
7123 if (r)
478 4 type = 'T';
479 }
480
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7121 times.
7123 while (lex_char(p, '+')) {
481
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_time(p, &dt))
482 2 return AVERROR_INVALIDDATA;
483 if (av_sat_add64(rel, dt) - dt != rel)
484 return AVERROR_INVALIDDATA;
485 rel += dt;
486 r = 1;
487 }
488
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7117 times.
7121 if (r) {
489
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if (!lex_space(p))
490 1 return AVERROR_INVALIDDATA;
491 3 rts->type = type;
492 3 rts->t = abs;
493 3 *rrel = rel;
494 }
495 7120 return r;
496 }
497
498 3 static int parse_fade(struct sbg_parser *p, struct sbg_fade *fr)
499 {
500 3 struct sbg_fade f = {0};
501
502
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (lex_char(p, '<'))
503 f.in = SBG_FADE_SILENCE;
504
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 else if (lex_char(p, '-'))
505 f.in = SBG_FADE_SAME;
506
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 else if (lex_char(p, '='))
507 f.in = SBG_FADE_ADAPT;
508 else
509 3 return 0;
510 if (lex_char(p, '>'))
511 f.out = SBG_FADE_SILENCE;
512 else if (lex_char(p, '-'))
513 f.out = SBG_FADE_SAME;
514 else if (lex_char(p, '='))
515 f.out = SBG_FADE_ADAPT;
516 else
517 return AVERROR_INVALIDDATA;
518 *fr = f;
519 return 1;
520 }
521
522 7123 static int parse_time_sequence(struct sbg_parser *p, int inblock)
523 {
524 struct sbg_timestamp ts;
525 int64_t rel_ts;
526 int r;
527 7123 struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 };
528 struct sbg_string name;
529 struct sbg_script_tseq *tseq;
530
531 7123 r = parse_timestamp(p, &ts, &rel_ts);
532
2/2
✓ Branch 0 taken 7117 times.
✓ Branch 1 taken 6 times.
7123 if (!r)
533 7117 return 0;
534
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (r < 0)
535 3 return r;
536
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ts.type) {
537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (inblock)
538 return AVERROR_INVALIDDATA;
539 3 p->current_time.type = ts.type;
540 3 p->current_time.t = ts.t;
541 } else if(!inblock && !p->current_time.type) {
542 snprintf(p->err_msg, sizeof(p->err_msg),
543 "relative time without previous absolute time");
544 return AVERROR_INVALIDDATA;
545 }
546 3 ts.type = p->current_time.type;
547
548
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (av_sat_add64(p->current_time.t, rel_ts) != p->current_time.t + (uint64_t)rel_ts)
549 return AVERROR_INVALIDDATA;
550 3 ts.t = p->current_time.t + rel_ts;
551 3 r = parse_fade(p, &fade);
552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (r < 0)
553 return r;
554 3 lex_space(p);
555
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!lex_name(p, &name))
556 return AVERROR_INVALIDDATA;
557 3 lex_space(p);
558
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (lex_fixed(p, "->", 2)) {
559 fade.slide = SBG_FADE_ADAPT;
560 lex_space(p);
561 }
562
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
3 if (!lex_line_end(p))
563 2 return AVERROR_INVALIDDATA;
564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 tseq = inblock ?
565 alloc_array_elem((void **)&p->scs.block_tseq, sizeof(*tseq),
566 &p->nb_block_tseq, &p->nb_block_tseq_max) :
567 1 alloc_array_elem((void **)&p->scs.tseq, sizeof(*tseq),
568 &p->scs.nb_tseq, &p->nb_tseq_max);
569
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!tseq)
570 return AVERROR(ENOMEM);
571 1 tseq->ts = ts;
572 1 tseq->name = name.s;
573 1 tseq->name_len = name.e - name.s;
574 1 tseq->fade = fade;
575 1 return 1;
576 }
577
578 static int parse_wave_def(struct sbg_parser *p, int wavenum)
579 {
580 snprintf(p->err_msg, sizeof(p->err_msg),
581 "waveform definitions not yet implemented");
582 return AVERROR_PATCHWELCOME;
583 }
584
585 static int parse_block_def(struct sbg_parser *p,
586 struct sbg_script_definition *def)
587 {
588 int r, tseq;
589
590 lex_space(p);
591 if (!lex_line_end(p))
592 return AVERROR_INVALIDDATA;
593 tseq = p->nb_block_tseq;
594 while (1) {
595 r = parse_time_sequence(p, 1);
596 if (r < 0)
597 return r;
598 if (!r)
599 break;
600 }
601 if (!lex_char(p, '}'))
602 return AVERROR_INVALIDDATA;
603 lex_space(p);
604 if (!lex_line_end(p))
605 return AVERROR_INVALIDDATA;
606 def->type = 'B';
607 def->elements = tseq;
608 def->nb_elements = p->nb_block_tseq - tseq;
609 if (!def->nb_elements)
610 return AVERROR_INVALIDDATA;
611 return 1;
612 }
613
614 2 static int parse_volume(struct sbg_parser *p, int *vol)
615 {
616 double v;
617
618
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_char(p, '/'))
619 2 return 0;
620 if (!lex_double(p, &v))
621 return AVERROR_INVALIDDATA;
622 if (scale_double(p->log, v, 0.01, vol))
623 return AVERROR(ERANGE);
624 return 1;
625 }
626
627 2 static int parse_synth_channel_sine(struct sbg_parser *p,
628 struct sbg_script_synth *synth)
629 {
630 double carrierf, beatf;
631 int carrier, beat, vol;
632
633
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!lex_double(p, &carrierf))
634 return 0;
635
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_double(p, &beatf))
636 2 beatf = 0;
637
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 FORWARD_ERROR(parse_volume(p, &vol));
638 if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
639 scale_double(p->log, beatf, 1, &beat) < 0)
640 return AVERROR(EDOM);
641 synth->type = SBG_TYPE_SINE;
642 synth->carrier = carrier;
643 synth->beat = beat;
644 synth->vol = vol;
645 return 1;
646 }
647
648 2 static int parse_synth_channel_pink(struct sbg_parser *p,
649 struct sbg_script_synth *synth)
650 {
651 int vol;
652
653
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "pink", 4))
654 2 return 0;
655 FORWARD_ERROR(parse_volume(p, &vol));
656 synth->type = SBG_TYPE_NOISE;
657 synth->vol = vol;
658 return 1;
659 }
660
661 2 static int parse_synth_channel_bell(struct sbg_parser *p,
662 struct sbg_script_synth *synth)
663 {
664 double carrierf;
665 int carrier, vol;
666
667
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "bell", 4))
668 2 return 0;
669 if (!lex_double(p, &carrierf))
670 return AVERROR_INVALIDDATA;
671 FORWARD_ERROR(parse_volume(p, &vol));
672 if (scale_double(p->log, carrierf, 1, &carrier) < 0)
673 return AVERROR(EDOM);
674 synth->type = SBG_TYPE_BELL;
675 synth->carrier = carrier;
676 synth->vol = vol;
677 return 1;
678 }
679
680 2 static int parse_synth_channel_mix(struct sbg_parser *p,
681 struct sbg_script_synth *synth)
682 {
683 int vol;
684
685
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "mix", 3))
686 2 return 0;
687 FORWARD_ERROR(parse_volume(p, &vol));
688 synth->type = SBG_TYPE_MIX;
689 synth->vol = vol;
690 return 1;
691 }
692
693 2 static int parse_synth_channel_spin(struct sbg_parser *p,
694 struct sbg_script_synth *synth)
695 {
696 double carrierf, beatf;
697 int carrier, beat, vol;
698
699
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "spin:", 5))
700 2 return 0;
701 if (!lex_double(p, &carrierf))
702 return AVERROR_INVALIDDATA;
703 if (!lex_double(p, &beatf))
704 return AVERROR_INVALIDDATA;
705 FORWARD_ERROR(parse_volume(p, &vol));
706 if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
707 scale_double(p->log, beatf, 1, &beat) < 0)
708 return AVERROR(EDOM);
709 synth->type = SBG_TYPE_SPIN;
710 synth->carrier = carrier;
711 synth->beat = beat;
712 synth->vol = vol;
713 return 1;
714 }
715
716 2 static int parse_synth_channel(struct sbg_parser *p)
717 {
718 int r;
719 struct sbg_script_synth *synth;
720
721 2 synth = alloc_array_elem((void **)&p->scs.synth, sizeof(*synth),
722 &p->scs.nb_synth, &p->nb_synth_max);
723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!synth)
724 return AVERROR(ENOMEM);
725 2 r = lex_char(p, '-');
726
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
727 2 r = parse_synth_channel_pink(p, synth);
728
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
729 2 r = parse_synth_channel_bell(p, synth);
730
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
731 2 r = parse_synth_channel_mix(p, synth);
732
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
733 2 r = parse_synth_channel_spin(p, synth);
734 /* Unimplemented: wave%d:%f%f/vol (carrier, beat) */
735
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
736 2 r = parse_synth_channel_sine(p, synth);
737
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (r <= 0)
738 2 p->scs.nb_synth--;
739 2 return r;
740 }
741
742 2 static int parse_synth_def(struct sbg_parser *p,
743 struct sbg_script_definition *def)
744 {
745 int r, synth;
746
747 2 synth = p->scs.nb_synth;
748 while (1) {
749 2 r = parse_synth_channel(p);
750
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (r < 0)
751 2 return r;
752 if (!r || !lex_space(p))
753 break;
754 }
755 lex_space(p);
756 if (synth == p->scs.nb_synth)
757 return AVERROR_INVALIDDATA;
758 if (!lex_line_end(p))
759 return AVERROR_INVALIDDATA;
760 def->type = 'S';
761 def->elements = synth;
762 def->nb_elements = p->scs.nb_synth - synth;
763 return 1;
764 }
765
766 7125 static int parse_named_def(struct sbg_parser *p)
767 {
768 7125 char *cursor_save = p->cursor;
769 struct sbg_string name;
770 struct sbg_script_definition *def;
771
772
6/6
✓ Branch 1 taken 1800 times.
✓ Branch 2 taken 5325 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 1790 times.
✓ Branch 7 taken 8 times.
✓ Branch 8 taken 2 times.
7125 if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) {
773 7123 p->cursor = cursor_save;
774 7123 return 0;
775 }
776
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (name.e - name.s == 6 && !memcmp(name.s, "wave", 4) &&
777 name.s[4] >= '0' && name.s[4] <= '9' &&
778 name.s[5] >= '0' && name.s[5] <= '9') {
779 int wavenum = (name.s[4] - '0') * 10 + (name.s[5] - '0');
780 return parse_wave_def(p, wavenum);
781 }
782 2 def = alloc_array_elem((void **)&p->scs.def, sizeof(*def),
783 &p->scs.nb_def, &p->nb_def_max);
784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!def)
785 return AVERROR(ENOMEM);
786 2 def->name = name.s;
787 2 def->name_len = name.e - name.s;
788
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (lex_char(p, '{'))
789 return parse_block_def(p, def);
790 2 return parse_synth_def(p, def);
791 }
792
793 14250 static void free_script(struct sbg_script *s)
794 {
795 14250 av_freep(&s->def);
796 14250 av_freep(&s->synth);
797 14250 av_freep(&s->tseq);
798 14250 av_freep(&s->block_tseq);
799 14250 av_freep(&s->events);
800 14250 av_freep(&s->opt_mix);
801 14250 }
802
803 7125 static int parse_script(void *log, char *script, int script_len,
804 struct sbg_script *rscript)
805 {
806 7125 struct sbg_parser sp = {
807 .log = log,
808 .script = script,
809 7125 .end = script + script_len,
810 .cursor = script,
811 .line_no = 1,
812 .err_msg = "",
813 .scs = {
814 /* default values */
815 .start_ts = AV_NOPTS_VALUE,
816 .sample_rate = 44100,
817 .opt_fade_time = 60 * AV_TIME_BASE,
818 },
819 };
820 int r;
821
822 7125 lex_space(&sp);
823
1/2
✓ Branch 0 taken 7230 times.
✗ Branch 1 not taken.
14355 while (sp.cursor < sp.end) {
824 7230 r = parse_options(&sp);
825
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7229 times.
7230 if (r < 0)
826 1 goto fail;
827
3/4
✓ Branch 0 taken 7229 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7124 times.
✓ Branch 4 taken 105 times.
7229 if (!r && !lex_line_end(&sp))
828 7124 break;
829 }
830
1/2
✓ Branch 0 taken 7125 times.
✗ Branch 1 not taken.
7125 while (sp.cursor < sp.end) {
831 7125 r = parse_named_def(&sp);
832
2/2
✓ Branch 0 taken 7123 times.
✓ Branch 1 taken 2 times.
7125 if (!r)
833 7123 r = parse_time_sequence(&sp, 0);
834
2/2
✓ Branch 0 taken 7117 times.
✓ Branch 1 taken 8 times.
7125 if (!r)
835
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7117 times.
7117 r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA;
836
2/2
✓ Branch 0 taken 7124 times.
✓ Branch 1 taken 1 times.
7125 if (r < 0)
837 7124 goto fail;
838 }
839 *rscript = sp.scs;
840 return 1;
841 7125 fail:
842 7125 free_script(&sp.scs);
843
2/2
✓ Branch 0 taken 7124 times.
✓ Branch 1 taken 1 times.
7125 if (!*sp.err_msg)
844
1/2
✓ Branch 0 taken 7124 times.
✗ Branch 1 not taken.
7124 if (r == AVERROR_INVALIDDATA)
845 7124 snprintf(sp.err_msg, sizeof(sp.err_msg), "syntax error");
846
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7125 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7125 if (log && *sp.err_msg) {
847 const char *ctx = sp.cursor;
848 const char *ectx = av_x_if_null(memchr(ctx, '\n', sp.end - sp.cursor),
849 sp.end);
850 int lctx = ectx - ctx;
851 const char *quote = "\"";
852 if (lctx > 0 && ctx[lctx - 1] == '\r')
853 lctx--;
854 if (lctx == 0) {
855 ctx = "the end of line";
856 lctx = strlen(ctx);
857 quote = "";
858 }
859 av_log(log, AV_LOG_ERROR, "Error line %d: %s near %s%.*s%s.\n",
860 sp.line_no, sp.err_msg, quote, lctx, ctx, quote);
861 }
862 7125 return r;
863 }
864
865 static int read_whole_file(AVIOContext *io, int max_size, AVBPrint *rbuf)
866 {
867 int ret = avio_read_to_bprint(io, rbuf, max_size);
868 if (ret < 0)
869 return ret;
870 if (!av_bprint_is_complete(rbuf))
871 return AVERROR(ENOMEM);
872 /* Check if we have read the whole file. AVIOContext.eof_reached is only
873 * set after a read failed due to EOF, so this check is incorrect in case
874 * max_size equals the actual file size, but checking for that would
875 * require attempting to read beyond max_size. */
876 if (!io->eof_reached)
877 return AVERROR(EFBIG);
878 return 0;
879 }
880
881 static int expand_timestamps(void *log, struct sbg_script *s)
882 {
883 int i, nb_rel = 0;
884 int64_t now, cur_ts, delta = 0;
885
886 for (i = 0; i < s->nb_tseq; i++)
887 nb_rel += s->tseq[i].ts.type == 'N';
888 if (nb_rel == s->nb_tseq) {
889 /* All ts are relative to NOW: consider NOW = 0 */
890 now = 0;
891 if (s->start_ts != AV_NOPTS_VALUE)
892 av_log(log, AV_LOG_WARNING,
893 "Start time ignored in a purely relative script.\n");
894 } else if (nb_rel == 0 && s->start_ts != AV_NOPTS_VALUE ||
895 s->opt_start_at_first) {
896 /* All ts are absolute and start time is specified */
897 if (s->start_ts == AV_NOPTS_VALUE)
898 s->start_ts = s->tseq[0].ts.t;
899 now = s->start_ts;
900 } else {
901 /* Mixed relative/absolute ts: expand */
902 time_t now0;
903 struct tm *tm, tmpbuf;
904
905 av_log(log, AV_LOG_WARNING,
906 "Scripts with mixed absolute and relative timestamps can give "
907 "unexpected results (pause, seeking, time zone change).\n");
908 #undef time
909 time(&now0);
910 tm = localtime_r(&now0, &tmpbuf);
911 now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec :
912 now0 % DAY;
913 av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n",
914 (int)(now / 3600), (int)(now / 60) % 60, (int)now % 60);
915 now *= AV_TIME_BASE;
916 for (i = 0; i < s->nb_tseq; i++) {
917 if (s->tseq[i].ts.type == 'N') {
918 s->tseq[i].ts.t += now;
919 s->tseq[i].ts.type = 'T'; /* not necessary */
920 }
921 }
922 }
923 if (s->start_ts == AV_NOPTS_VALUE)
924 s->start_ts = (s->opt_start_at_first && s->tseq) ? s->tseq[0].ts.t : now;
925 if (s->start_ts > INT64_MAX - s->opt_duration)
926 return AVERROR_INVALIDDATA;
927
928 s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration :
929 AV_NOPTS_VALUE; /* may be overridden later by -E option */
930 cur_ts = now;
931 for (i = 0; i < s->nb_tseq; i++) {
932 if (av_sat_add64(s->tseq[i].ts.t, delta) != s->tseq[i].ts.t + (uint64_t)delta)
933 return AVERROR_INVALIDDATA;
934 if (s->tseq[i].ts.t + delta < cur_ts)
935 delta += DAY_TS;
936 cur_ts = s->tseq[i].ts.t += delta;
937 }
938 return 0;
939 }
940
941 static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
942 int64_t t0, struct sbg_script_tseq *tseq)
943 {
944 int i, r;
945 struct sbg_script_definition *def;
946 struct sbg_script_tseq *be;
947 struct sbg_script_event *ev;
948
949 if (tseq->lock++) {
950 av_log(log, AV_LOG_ERROR, "Recursion loop on \"%.*s\"\n",
951 tseq->name_len, tseq->name);
952 return AVERROR(EINVAL);
953 }
954 if (t0 + (uint64_t)tseq->ts.t != av_sat_add64(t0, tseq->ts.t))
955 return AVERROR(EINVAL);
956
957 t0 += tseq->ts.t;
958 for (i = 0; i < s->nb_def; i++) {
959 if (s->def[i].name_len == tseq->name_len &&
960 !memcmp(s->def[i].name, tseq->name, tseq->name_len))
961 break;
962 }
963 if (i >= s->nb_def) {
964 av_log(log, AV_LOG_ERROR, "Tone-set \"%.*s\" not defined\n",
965 tseq->name_len, tseq->name);
966 return AVERROR(EINVAL);
967 }
968 def = &s->def[i];
969 if (def->type == 'B') {
970 be = s->block_tseq + def->elements;
971 for (i = 0; i < def->nb_elements; i++) {
972 r = expand_tseq(log, s, nb_ev_max, t0, &be[i]);
973 if (r < 0)
974 return r;
975 }
976 } else {
977 ev = alloc_array_elem((void **)&s->events, sizeof(*ev),
978 &s->nb_events, nb_ev_max);
979 if (!ev)
980 return AVERROR(ENOMEM);
981 ev->ts = tseq->ts.t;
982 ev->elements = def->elements;
983 ev->nb_elements = def->nb_elements;
984 ev->fade = tseq->fade;
985 }
986 tseq->lock--;
987 return 0;
988 }
989
990 static int expand_script(void *log, struct sbg_script *s)
991 {
992 int i, r, nb_events_max = 0;
993
994 r = expand_timestamps(log, s);
995 if (r < 0)
996 return r;
997 for (i = 0; i < s->nb_tseq; i++) {
998 r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]);
999 if (r < 0)
1000 return r;
1001 }
1002 if (!s->nb_events) {
1003 av_log(log, AV_LOG_ERROR, "No events in script\n");
1004 return AVERROR_INVALIDDATA;
1005 }
1006 if (s->opt_end_at_last)
1007 s->end_ts = s->events[s->nb_events - 1].ts;
1008 return 0;
1009 }
1010
1011 static int add_interval(struct ws_intervals *inter,
1012 enum ws_interval_type type, uint32_t channels, int ref,
1013 int64_t ts1, int32_t f1, int32_t a1,
1014 int64_t ts2, int32_t f2, int32_t a2)
1015 {
1016 struct ws_interval *i, *ri;
1017
1018 if (ref >= 0) {
1019 ri = &inter->inter[ref];
1020 /* ref and new intervals are constant, identical and adjacent */
1021 if (ri->type == type && ri->channels == channels &&
1022 ri->f1 == ri->f2 && ri->f2 == f1 && f1 == f2 &&
1023 ri->a1 == ri->a2 && ri->a2 == a1 && a1 == a2 &&
1024 ri->ts2 == ts1) {
1025 ri->ts2 = ts2;
1026 return ref;
1027 }
1028 }
1029 i = alloc_array_elem((void **)&inter->inter, sizeof(*i),
1030 &inter->nb_inter, &inter->max_inter);
1031 if (!i)
1032 return AVERROR(ENOMEM);
1033 i->ts1 = ts1;
1034 i->ts2 = ts2;
1035 i->type = type;
1036 i->channels = channels;
1037 i->f1 = f1;
1038 i->f2 = f2;
1039 i->a1 = a1;
1040 i->a2 = a2;
1041 i->phi = ref >= 0 ? ref | 0x80000000 : 0;
1042 return i - inter->inter;
1043 }
1044
1045 static int add_bell(struct ws_intervals *inter, struct sbg_script *s,
1046 int64_t ts1, int64_t ts2, int32_t f, int32_t a)
1047 {
1048 /* SBaGen uses an exponential decrease every 50ms.
1049 We approximate it with piecewise affine segments. */
1050 int32_t cpoints[][2] = {
1051 { 2, a },
1052 { 4, a - a / 4 },
1053 { 8, a / 2 },
1054 { 16, a / 4 },
1055 { 25, a / 10 },
1056 { 50, a / 80 },
1057 { 75, 0 },
1058 };
1059 int i, r;
1060 int64_t dt = s->sample_rate / 20, ts3 = ts1, ts4;
1061 for (i = 0; i < FF_ARRAY_ELEMS(cpoints); i++) {
1062 ts4 = FFMIN(ts2, ts1 + cpoints[i][0] * dt);
1063 r = add_interval(inter, WS_SINE, 3, -1,
1064 ts3, f, a, ts4, f, cpoints[i][1]);
1065 if (r < 0)
1066 return r;
1067 ts3 = ts4;
1068 a = cpoints[i][1];
1069 }
1070 return 0;
1071 }
1072
1073 static int generate_interval(void *log, struct sbg_script *s,
1074 struct ws_intervals *inter,
1075 int64_t ts1, int64_t ts2,
1076 struct sbg_script_synth *s1,
1077 struct sbg_script_synth *s2,
1078 int transition)
1079 {
1080 int r;
1081
1082 if (ts2 <= ts1 || (s1->vol == 0 && s2->vol == 0))
1083 return 0;
1084 switch (s1->type) {
1085 case SBG_TYPE_NONE:
1086 break;
1087 case SBG_TYPE_SINE:
1088 if (s1->beat == 0 && s2->beat == 0) {
1089 r = add_interval(inter, WS_SINE, 3, s1->ref.l,
1090 ts1, s1->carrier, s1->vol,
1091 ts2, s2->carrier, s2->vol);
1092 if (r < 0)
1093 return r;
1094 s2->ref.l = s2->ref.r = r;
1095 } else {
1096 r = add_interval(inter, WS_SINE, 1, s1->ref.l,
1097 ts1, s1->carrier + s1->beat / 2, s1->vol,
1098 ts2, s2->carrier + s2->beat / 2, s2->vol);
1099 if (r < 0)
1100 return r;
1101 s2->ref.l = r;
1102 r = add_interval(inter, WS_SINE, 2, s1->ref.r,
1103 ts1, s1->carrier - s1->beat / 2, s1->vol,
1104 ts2, s2->carrier - s2->beat / 2, s2->vol);
1105 if (r < 0)
1106 return r;
1107 s2->ref.r = r;
1108 }
1109 break;
1110
1111 case SBG_TYPE_BELL:
1112 if (transition == 2) {
1113 r = add_bell(inter, s, ts1, ts2, s1->carrier, s2->vol);
1114 if (r < 0)
1115 return r;
1116 }
1117 break;
1118
1119 case SBG_TYPE_SPIN:
1120 av_log(log, AV_LOG_WARNING, "Spinning noise not implemented, "
1121 "using pink noise instead.\n");
1122 /* fall through */
1123 case SBG_TYPE_NOISE:
1124 /* SBaGen's pink noise generator uses:
1125 - 1 band of white noise, mean square: 1/3;
1126 - 9 bands of subsampled white noise with linear
1127 interpolation, mean square: 2/3 each;
1128 with 1/10 weight each: the total mean square is 7/300.
1129 Our pink noise generator uses 8 bands of white noise with
1130 rectangular subsampling: the total mean square is 1/24.
1131 Therefore, to match SBaGen's volume, we must multiply vol by
1132 sqrt((7/300) / (1/24)) = sqrt(14/25) =~ 0.748
1133 */
1134 r = add_interval(inter, WS_NOISE, 3, s1->ref.l,
1135 ts1, 0, s1->vol - s1->vol / 4,
1136 ts2, 0, s2->vol - s2->vol / 4);
1137 if (r < 0)
1138 return r;
1139 s2->ref.l = s2->ref.r = r;
1140 break;
1141
1142 case SBG_TYPE_MIX:
1143 /* Unimplemented: silence; warning present elsewhere */
1144 default:
1145 av_log(log, AV_LOG_ERROR,
1146 "Type %d is not implemented\n", s1->type);
1147 return AVERROR_PATCHWELCOME;
1148 }
1149 return 0;
1150 }
1151
1152 static int generate_plateau(void *log, struct sbg_script *s,
1153 struct ws_intervals *inter,
1154 struct sbg_script_event *ev1)
1155 {
1156 int64_t ts1 = ev1->ts_int, ts2 = ev1->ts_trans;
1157 int i, r;
1158 struct sbg_script_synth *s1;
1159
1160 for (i = 0; i < ev1->nb_elements; i++) {
1161 s1 = &s->synth[ev1->elements + i];
1162 r = generate_interval(log, s, inter, ts1, ts2, s1, s1, 0);
1163 if (r < 0)
1164 return r;
1165 }
1166 return 0;
1167 }
1168
1169 /*
1170
1171 ts1 ts2 ts1 tsmid ts2
1172 | | | | |
1173 v v v | v
1174 ____ ____ v ____
1175 ''''.... ''.. ..''
1176 ''''....____ ''....''
1177
1178 compatible transition incompatible transition
1179 */
1180
1181 static int generate_transition(void *log, struct sbg_script *s,
1182 struct ws_intervals *inter,
1183 struct sbg_script_event *ev1,
1184 struct sbg_script_event *ev2)
1185 {
1186 int64_t ts1 = ev1->ts_trans, ts2 = ev1->ts_next;
1187 /* (ts1 + ts2) / 2 without overflow */
1188 int64_t tsmid = (ts1 >> 1) + (ts2 >> 1) + (ts1 & ts2 & 1);
1189 enum sbg_fade_type type = ev1->fade.slide | (ev1->fade.out & ev2->fade.in);
1190 int nb_elements = FFMAX(ev1->nb_elements, ev2->nb_elements);
1191 struct sbg_script_synth *s1, *s2, s1mod, s2mod, smid;
1192 int pass, i, r;
1193
1194 for (pass = 0; pass < 2; pass++) {
1195 /* pass = 0 -> compatible and first half of incompatible
1196 pass = 1 -> second half of incompatible
1197 Using two passes like that ensures that the intervals are generated
1198 in increasing order according to their start timestamp.
1199 Otherwise it would be necessary to sort them
1200 while keeping the mutual references.
1201 */
1202 for (i = 0; i < nb_elements; i++) {
1203 s1 = i < ev1->nb_elements ? &s->synth[ev1->elements + i] : &s1mod;
1204 s2 = i < ev2->nb_elements ? &s->synth[ev2->elements + i] : &s2mod;
1205 s1mod = s1 != &s1mod ? *s1 : (struct sbg_script_synth){ 0 };
1206 s2mod = s2 != &s2mod ? *s2 : (struct sbg_script_synth){ 0 };
1207 if (ev1->fade.slide) {
1208 /* for slides, and only for slides, silence ("-") is equivalent
1209 to anything with volume 0 */
1210 if (s1mod.type == SBG_TYPE_NONE) {
1211 s1mod = s2mod;
1212 s1mod.vol = 0;
1213 } else if (s2mod.type == SBG_TYPE_NONE) {
1214 s2mod = s1mod;
1215 s2mod.vol = 0;
1216 }
1217 }
1218 if (s1mod.type == s2mod.type &&
1219 s1mod.type != SBG_TYPE_BELL &&
1220 (type == SBG_FADE_ADAPT ||
1221 (s1mod.carrier == s2mod.carrier &&
1222 s1mod.beat == s2mod.beat))) {
1223 /* compatible: single transition */
1224 if (!pass) {
1225 r = generate_interval(log, s, inter,
1226 ts1, ts2, &s1mod, &s2mod, 3);
1227 if (r < 0)
1228 return r;
1229 s2->ref = s2mod.ref;
1230 }
1231 } else {
1232 /* incompatible: silence at midpoint */
1233 if (!pass) {
1234 smid = s1mod;
1235 smid.vol = 0;
1236 r = generate_interval(log, s, inter,
1237 ts1, tsmid, &s1mod, &smid, 1);
1238 if (r < 0)
1239 return r;
1240 } else {
1241 smid = s2mod;
1242 smid.vol = 0;
1243 r = generate_interval(log, s, inter,
1244 tsmid, ts2, &smid, &s2mod, 2);
1245 if (r < 0)
1246 return r;
1247 s2->ref = s2mod.ref;
1248 }
1249 }
1250 }
1251 }
1252 return 0;
1253 }
1254
1255 /*
1256 ev1 trats ev2 intts endts ev3
1257 | | | | | |
1258 v v v v v v
1259 ________________
1260 .... .... ....
1261 '''....________________....''' '''...._______________
1262
1263 \_________/\______________/\_________/\______________/\_________/\_____________/
1264 tr x->1 int1 tr 1->2 int2 tr 2->3 int3
1265 */
1266
1267 static int generate_intervals(void *log, struct sbg_script *s, int sample_rate,
1268 struct ws_intervals *inter)
1269 {
1270 int64_t trans_time = s->opt_fade_time / 2;
1271 struct sbg_script_event ev0, *ev1, *ev2;
1272 int64_t period;
1273 int i, r;
1274
1275 /* SBaGen handles the time before and after the extremal events,
1276 and the corresponding transitions, as if the sequence were cyclic
1277 with a 24-hours period. */
1278 period = s->events[s->nb_events - 1].ts - (uint64_t)s->events[0].ts;
1279 if (period < 0)
1280 return AVERROR_INVALIDDATA;
1281
1282 period = (period + (DAY_TS - 1)) / DAY_TS * DAY_TS;
1283 period = FFMAX(period, DAY_TS);
1284
1285 /* Prepare timestamps for transitions */
1286 for (i = 0; i < s->nb_events; i++) {
1287 ev1 = &s->events[i];
1288 ev2 = &s->events[(i + 1) % s->nb_events];
1289 ev1->ts_int = ev1->ts;
1290
1291 if (!ev1->fade.slide && ev1 >= ev2 && ev2->ts > INT64_MAX - period)
1292 return AVERROR_INVALIDDATA;
1293
1294 ev1->ts_trans = ev1->fade.slide ? ev1->ts
1295 : ev2->ts + (ev1 < ev2 ? 0 : period);
1296 }
1297 for (i = 0; i < s->nb_events; i++) {
1298 ev1 = &s->events[i];
1299 ev2 = &s->events[(i + 1) % s->nb_events];
1300 if (!ev1->fade.slide) {
1301 ev1->ts_trans = FFMAX(ev1->ts_int, ev1->ts_trans - trans_time);
1302 ev2->ts_int = FFMIN(ev2->ts_trans, ev2->ts_int + trans_time);
1303 }
1304 ev1->ts_next = ev2->ts_int + (ev1 < ev2 ? 0 : period);
1305 }
1306
1307 /* Pseudo event before the first one */
1308 ev0 = s->events[s->nb_events - 1];
1309 if (av_sat_sub64(ev0.ts_int, period) != (uint64_t)ev0.ts_int - period)
1310 return AVERROR_INVALIDDATA;
1311 ev0.ts_int -= period;
1312 ev0.ts_trans -= period;
1313 ev0.ts_next -= period;
1314
1315 /* Convert timestamps */
1316 for (i = -1; i < s->nb_events; i++) {
1317 ev1 = i < 0 ? &ev0 : &s->events[i];
1318 ev1->ts_int = av_rescale(ev1->ts_int, sample_rate, AV_TIME_BASE);
1319 ev1->ts_trans = av_rescale(ev1->ts_trans, sample_rate, AV_TIME_BASE);
1320 ev1->ts_next = av_rescale(ev1->ts_next, sample_rate, AV_TIME_BASE);
1321 }
1322
1323 /* Generate intervals */
1324 for (i = 0; i < s->nb_synth; i++)
1325 s->synth[i].ref.l = s->synth[i].ref.r = -1;
1326 for (i = -1; i < s->nb_events; i++) {
1327 ev1 = i < 0 ? &ev0 : &s->events[i];
1328 ev2 = &s->events[(i + 1) % s->nb_events];
1329 r = generate_plateau(log, s, inter, ev1);
1330 if (r < 0)
1331 return r;
1332 r = generate_transition(log, s, inter, ev1, ev2);
1333 if (r < 0)
1334 return r;
1335 }
1336 if (!inter->nb_inter)
1337 av_log(log, AV_LOG_WARNING, "Completely silent script.\n");
1338 return 0;
1339 }
1340
1341 static int encode_intervals(struct sbg_script *s, AVCodecParameters *par,
1342 struct ws_intervals *inter)
1343 {
1344 int i, edata_size = 4, ret;
1345 uint8_t *edata;
1346
1347 for (i = 0; i < inter->nb_inter; i++) {
1348 edata_size += inter->inter[i].type == WS_SINE ? 44 :
1349 inter->inter[i].type == WS_NOISE ? 32 : 0;
1350 if (edata_size < 0)
1351 return AVERROR(ENOMEM);
1352 }
1353 if ((ret = ff_alloc_extradata(par, edata_size)) < 0)
1354 return ret;
1355 edata = par->extradata;
1356
1357 #define ADD_EDATA32(v) do { AV_WL32(edata, (v)); edata += 4; } while(0)
1358 #define ADD_EDATA64(v) do { AV_WL64(edata, (v)); edata += 8; } while(0)
1359 ADD_EDATA32(inter->nb_inter);
1360 for (i = 0; i < inter->nb_inter; i++) {
1361 ADD_EDATA64(inter->inter[i].ts1);
1362 ADD_EDATA64(inter->inter[i].ts2);
1363 ADD_EDATA32(inter->inter[i].type);
1364 ADD_EDATA32(inter->inter[i].channels);
1365 switch (inter->inter[i].type) {
1366 case WS_SINE:
1367 ADD_EDATA32(inter->inter[i].f1);
1368 ADD_EDATA32(inter->inter[i].f2);
1369 ADD_EDATA32(inter->inter[i].a1);
1370 ADD_EDATA32(inter->inter[i].a2);
1371 ADD_EDATA32(inter->inter[i].phi);
1372 break;
1373 case WS_NOISE:
1374 ADD_EDATA32(inter->inter[i].a1);
1375 ADD_EDATA32(inter->inter[i].a2);
1376 break;
1377 }
1378 }
1379 if (edata != par->extradata + edata_size)
1380 return AVERROR_BUG;
1381 return 0;
1382 }
1383
1384 7125 static av_cold int sbg_read_probe(const AVProbeData *p)
1385 {
1386 int r, score;
1387 7125 struct sbg_script script = { 0 };
1388
1389 7125 r = parse_script(NULL, p->buf, p->buf_size, &script);
1390
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7125 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7125 score = r < 0 || !script.nb_def || !script.nb_tseq ? 0 :
1391 AVPROBE_SCORE_MAX / 3;
1392 7125 free_script(&script);
1393 7125 return score;
1394 }
1395
1396 static av_cold int sbg_read_header(AVFormatContext *avf)
1397 {
1398 struct sbg_demuxer *sbg = avf->priv_data;
1399 AVBPrint bprint;
1400 int r;
1401 struct sbg_script script = { 0 };
1402 AVStream *st;
1403 FFStream *sti;
1404 struct ws_intervals inter = { 0 };
1405
1406 av_bprint_init(&bprint, 0, sbg->max_file_size + 1U);
1407 r = read_whole_file(avf->pb, sbg->max_file_size, &bprint);
1408 if (r < 0)
1409 goto fail2;
1410
1411 r = parse_script(avf, bprint.str, bprint.len, &script);
1412 if (r < 0)
1413 goto fail2;
1414 if (!sbg->sample_rate)
1415 sbg->sample_rate = script.sample_rate;
1416 else
1417 script.sample_rate = sbg->sample_rate;
1418 if (!sbg->frame_size)
1419 sbg->frame_size = FFMAX(1, sbg->sample_rate / 10);
1420 if (script.opt_mix)
1421 av_log(avf, AV_LOG_WARNING, "Mix feature not implemented: "
1422 "-m is ignored and mix channels will be silent.\n");
1423 r = expand_script(avf, &script);
1424 if (r < 0)
1425 goto fail2;
1426 av_bprint_finalize(&bprint, NULL);
1427 r = generate_intervals(avf, &script, sbg->sample_rate, &inter);
1428 if (r < 0)
1429 goto fail;
1430
1431 if (script.end_ts != AV_NOPTS_VALUE && script.end_ts < script.start_ts) {
1432 r = AVERROR_INVALIDDATA;
1433 goto fail;
1434 }
1435
1436 st = avformat_new_stream(avf, NULL);
1437 if (!st)
1438 return AVERROR(ENOMEM);
1439 sti = ffstream(st);
1440 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
1441 st->codecpar->codec_id = AV_CODEC_ID_FFWAVESYNTH;
1442 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
1443 st->codecpar->sample_rate = sbg->sample_rate;
1444 st->codecpar->frame_size = sbg->frame_size;
1445 avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
1446 sti->probe_packets = 0;
1447 st->start_time = av_rescale(script.start_ts,
1448 sbg->sample_rate, AV_TIME_BASE);
1449 st->duration = script.end_ts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
1450 av_rescale(script.end_ts - script.start_ts,
1451 sbg->sample_rate, AV_TIME_BASE);
1452
1453 if (st->duration != AV_NOPTS_VALUE && (
1454 st->duration < 0 || st->start_time > INT64_MAX - st->duration)) {
1455 r = AVERROR_INVALIDDATA;
1456 goto fail;
1457 }
1458
1459 sti->cur_dts = st->start_time;
1460 r = encode_intervals(&script, st->codecpar, &inter);
1461 if (r < 0)
1462 goto fail;
1463
1464 av_free(inter.inter);
1465 free_script(&script);
1466 return 0;
1467
1468 fail2:
1469 av_bprint_finalize(&bprint, NULL);
1470 fail:
1471 av_free(inter.inter);
1472 free_script(&script);
1473 return r;
1474 }
1475
1476 static int sbg_read_packet(AVFormatContext *avf, AVPacket *packet)
1477 {
1478 int64_t ts, end_ts;
1479 int ret;
1480
1481 ts = ffstream(avf->streams[0])->cur_dts;
1482 end_ts = av_sat_add64(ts, avf->streams[0]->codecpar->frame_size);
1483 if (avf->streams[0]->duration != AV_NOPTS_VALUE)
1484 end_ts = FFMIN(avf->streams[0]->start_time + avf->streams[0]->duration,
1485 end_ts);
1486 if (end_ts <= ts)
1487 return AVERROR_EOF;
1488 if ((ret = av_new_packet(packet, 12)) < 0)
1489 return ret;
1490 packet->dts = packet->pts = ts;
1491 packet->duration = end_ts - ts;
1492 AV_WL64(packet->data + 0, ts);
1493 AV_WL32(packet->data + 8, packet->duration);
1494 return packet->size;
1495 }
1496
1497 static int sbg_read_seek2(AVFormatContext *avf, int stream_index,
1498 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
1499 {
1500 if (flags || stream_index > 0)
1501 return AVERROR(EINVAL);
1502 if (stream_index < 0)
1503 ts = av_rescale_q(ts, AV_TIME_BASE_Q, avf->streams[0]->time_base);
1504 ffstream(avf->streams[0])->cur_dts = ts;
1505 return 0;
1506 }
1507
1508 static int sbg_read_seek(AVFormatContext *avf, int stream_index,
1509 int64_t ts, int flags)
1510 {
1511 return sbg_read_seek2(avf, stream_index, ts, ts, ts, 0);
1512 }
1513
1514 static const AVOption sbg_options[] = {
1515 { "sample_rate", "", offsetof(struct sbg_demuxer, sample_rate),
1516 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1517 AV_OPT_FLAG_DECODING_PARAM },
1518 { "frame_size", "", offsetof(struct sbg_demuxer, frame_size),
1519 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1520 AV_OPT_FLAG_DECODING_PARAM },
1521 { "max_file_size", "", offsetof(struct sbg_demuxer, max_file_size),
1522 AV_OPT_TYPE_INT, { .i64 = 5000000 }, 0, INT_MAX,
1523 AV_OPT_FLAG_DECODING_PARAM },
1524 { NULL },
1525 };
1526
1527 static const AVClass sbg_demuxer_class = {
1528 .class_name = "sbg_demuxer",
1529 .item_name = av_default_item_name,
1530 .option = sbg_options,
1531 .version = LIBAVUTIL_VERSION_INT,
1532 };
1533
1534 const FFInputFormat ff_sbg_demuxer = {
1535 .p.name = "sbg",
1536 .p.long_name = NULL_IF_CONFIG_SMALL("SBaGen binaural beats script"),
1537 .p.extensions = "sbg",
1538 .p.priv_class = &sbg_demuxer_class,
1539 .priv_data_size = sizeof(struct sbg_demuxer),
1540 .read_probe = sbg_read_probe,
1541 .read_header = sbg_read_header,
1542 .read_packet = sbg_read_packet,
1543 .read_seek = sbg_read_seek,
1544 .read_seek2 = sbg_read_seek2,
1545 };
1546