FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/sbgdec.c
Date: 2026-04-20 20:24:43
Exec Total Coverage
Lines: 246 865 28.4%
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 7467 static int str_to_time(const char *str, int64_t *rtime)
183 {
184 7467 const char *cur = str;
185 char *end;
186 int hours, minutes;
187 7467 double seconds = 0;
188 7467 int64_t ts = 0;
189
190
4/4
✓ Branch 0 taken 1929 times.
✓ Branch 1 taken 5538 times.
✓ Branch 2 taken 1865 times.
✓ Branch 3 taken 64 times.
7467 if (*cur < '0' || *cur > '9')
191 7403 return 0;
192 64 hours = strtol(cur, &end, 10);
193
5/8
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
64 if (end == cur || *end != ':' || end[1] < '0' || end[1] > '9')
194 60 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 7624 static inline int is_space(char c)
211 {
212
6/6
✓ Branch 0 taken 7617 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7615 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7614 times.
7624 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 7607 static int lex_space(struct sbg_parser *p)
228 {
229 7607 char *c = p->cursor;
230
231
3/4
✓ Branch 0 taken 7616 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 7607 times.
7616 while (p->cursor < p->end && is_space(*p->cursor))
232 9 p->cursor++;
233 7607 return p->cursor > c;
234 }
235
236 9357 static int lex_char(struct sbg_parser *p, char c)
237 {
238
3/4
✓ Branch 0 taken 9357 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 9343 times.
9357 int r = p->cursor < p->end && *p->cursor == c;
239
240 9357 p->cursor += r;
241 9357 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 7476 static int lex_fixed(struct sbg_parser *p, const char *t, int l)
261 {
262
2/4
✓ Branch 0 taken 7476 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7476 times.
✗ Branch 3 not taken.
7476 if (p->end - p->cursor < l || memcmp(p->cursor, t, l))
263 7476 return 0;
264 p->cursor += l;
265 return 1;
266 }
267
268 15045 static int lex_line_end(struct sbg_parser *p)
269 {
270
3/4
✓ Branch 0 taken 15045 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 115 times.
✓ Branch 3 taken 14930 times.
15045 if (p->cursor < p->end && *p->cursor == '#') {
271 115 p->cursor++;
272
3/4
✓ Branch 0 taken 11443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11328 times.
✓ Branch 3 taken 115 times.
11443 while (p->cursor < p->end && *p->cursor != '\n')
273 11328 p->cursor++;
274 }
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15045 times.
15045 if (p->cursor == p->end)
276 /* simulate final LF for files lacking it */
277 return 1;
278
2/2
✓ Branch 0 taken 14927 times.
✓ Branch 1 taken 118 times.
15045 if (*p->cursor != '\n')
279 14927 return 0;
280 118 p->cursor++;
281 118 p->line_no++;
282 118 lex_space(p);
283 118 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 7470 static int lex_name(struct sbg_parser *p, struct sbg_string *rs)
301 {
302 7470 char *s = p->cursor, *c = s;
303
304
9/10
✓ Branch 0 taken 14932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
✓ Branch 3 taken 13813 times.
✓ Branch 4 taken 1071 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 6186 times.
✓ Branch 7 taken 7675 times.
✓ Branch 8 taken 6075 times.
✓ Branch 9 taken 111 times.
14932 while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
305
8/8
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 7241 times.
✓ Branch 2 taken 268 times.
✓ Branch 3 taken 277 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 7485 times.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 7470 times.
7786 || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-'))
306 7462 c++;
307
2/2
✓ Branch 0 taken 5591 times.
✓ Branch 1 taken 1879 times.
7470 if (c == s)
308 5591 return 0;
309 1879 rs->s = s;
310 1879 rs->e = p->cursor = c;
311 1879 return 1;
312 }
313
314 7467 static int lex_time(struct sbg_parser *p, int64_t *rt)
315 {
316 7467 int r = str_to_time(p->cursor, rt);
317 7467 p->cursor += r;
318 7467 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 7584 static int parse_options(struct sbg_parser *p)
353 {
354 struct sbg_string ostr, oarg;
355 7584 char mode = 0;
356 int r;
357 char *tptr;
358 double v;
359
360
3/4
✓ Branch 0 taken 7584 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7583 times.
✓ Branch 3 taken 1 times.
7584 if (p->cursor == p->end || *p->cursor != '-')
361 7583 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 7465 static int parse_timestamp(struct sbg_parser *p,
466 struct sbg_timestamp *rts, int64_t *rrel)
467 {
468 7465 int64_t abs = 0, rel = 0, dt;
469 7465 char type = 0;
470 int r;
471
472
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7465 times.
7465 if (lex_fixed(p, "NOW", 3)) {
473 type = 'N';
474 r = 1;
475 } else {
476 7465 r = lex_time(p, &abs);
477
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7461 times.
7465 if (r)
478 4 type = 'T';
479 }
480
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7463 times.
7465 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 7459 times.
7463 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 7462 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 7465 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 7465 struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 };
528 struct sbg_string name;
529 struct sbg_script_tseq *tseq;
530
531 7465 r = parse_timestamp(p, &ts, &rel_ts);
532
2/2
✓ Branch 0 taken 7459 times.
✓ Branch 1 taken 6 times.
7465 if (!r)
533 7459 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 7467 static int parse_named_def(struct sbg_parser *p)
767 {
768 7467 char *cursor_save = p->cursor;
769 struct sbg_string name;
770 struct sbg_script_definition *def;
771
772
6/6
✓ Branch 1 taken 1876 times.
✓ Branch 2 taken 5591 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 1865 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 2 times.
7467 if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) {
773 7465 p->cursor = cursor_save;
774 7465 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 14934 static void free_script(struct sbg_script *s)
794 {
795 14934 av_freep(&s->def);
796 14934 av_freep(&s->synth);
797 14934 av_freep(&s->tseq);
798 14934 av_freep(&s->block_tseq);
799 14934 av_freep(&s->events);
800 14934 av_freep(&s->opt_mix);
801 14934 }
802
803 7467 static int parse_script(void *log, char *script, int script_len,
804 struct sbg_script *rscript)
805 {
806 7467 struct sbg_parser sp = {
807 .log = log,
808 .script = script,
809 7467 .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 7467 lex_space(&sp);
823
1/2
✓ Branch 0 taken 7584 times.
✗ Branch 1 not taken.
15051 while (sp.cursor < sp.end) {
824 7584 r = parse_options(&sp);
825
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7583 times.
7584 if (r < 0)
826 1 goto fail;
827
3/4
✓ Branch 0 taken 7583 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7466 times.
✓ Branch 4 taken 117 times.
7583 if (!r && !lex_line_end(&sp))
828 7466 break;
829 }
830
1/2
✓ Branch 0 taken 7467 times.
✗ Branch 1 not taken.
7467 while (sp.cursor < sp.end) {
831 7467 r = parse_named_def(&sp);
832
2/2
✓ Branch 0 taken 7465 times.
✓ Branch 1 taken 2 times.
7467 if (!r)
833 7465 r = parse_time_sequence(&sp, 0);
834
2/2
✓ Branch 0 taken 7459 times.
✓ Branch 1 taken 8 times.
7467 if (!r)
835
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7459 times.
7459 r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA;
836
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 1 times.
7467 if (r < 0)
837 7466 goto fail;
838 }
839 *rscript = sp.scs;
840 return 1;
841 7467 fail:
842 7467 free_script(&sp.scs);
843
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 1 times.
7467 if (!*sp.err_msg)
844
1/2
✓ Branch 0 taken 7466 times.
✗ Branch 1 not taken.
7466 if (r == AVERROR_INVALIDDATA)
845 7466 snprintf(sp.err_msg, sizeof(sp.err_msg), "syntax error");
846
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7467 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7467 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 7467 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 time(&now0);
909 tm = localtime_r(&now0, &tmpbuf);
910 now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec :
911 now0 % DAY;
912 av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n",
913 (int)(now / 3600), (int)(now / 60) % 60, (int)now % 60);
914 now *= AV_TIME_BASE;
915 for (i = 0; i < s->nb_tseq; i++) {
916 if (s->tseq[i].ts.type == 'N') {
917 s->tseq[i].ts.t += now;
918 s->tseq[i].ts.type = 'T'; /* not necessary */
919 }
920 }
921 }
922 if (s->start_ts == AV_NOPTS_VALUE)
923 s->start_ts = (s->opt_start_at_first && s->tseq) ? s->tseq[0].ts.t : now;
924 if (s->start_ts > INT64_MAX - s->opt_duration)
925 return AVERROR_INVALIDDATA;
926
927 s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration :
928 AV_NOPTS_VALUE; /* may be overridden later by -E option */
929 cur_ts = now;
930 for (i = 0; i < s->nb_tseq; i++) {
931 if (av_sat_add64(s->tseq[i].ts.t, delta) != s->tseq[i].ts.t + (uint64_t)delta)
932 return AVERROR_INVALIDDATA;
933 if (s->tseq[i].ts.t + delta < cur_ts)
934 delta += DAY_TS;
935 cur_ts = s->tseq[i].ts.t += delta;
936 }
937 return 0;
938 }
939
940 static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
941 int64_t t0, struct sbg_script_tseq *tseq)
942 {
943 int i, r;
944 struct sbg_script_definition *def;
945 struct sbg_script_tseq *be;
946 struct sbg_script_event *ev;
947
948 if (tseq->lock++) {
949 av_log(log, AV_LOG_ERROR, "Recursion loop on \"%.*s\"\n",
950 tseq->name_len, tseq->name);
951 return AVERROR(EINVAL);
952 }
953 if (t0 + (uint64_t)tseq->ts.t != av_sat_add64(t0, tseq->ts.t))
954 return AVERROR(EINVAL);
955
956 t0 += tseq->ts.t;
957 for (i = 0; i < s->nb_def; i++) {
958 if (s->def[i].name_len == tseq->name_len &&
959 !memcmp(s->def[i].name, tseq->name, tseq->name_len))
960 break;
961 }
962 if (i >= s->nb_def) {
963 av_log(log, AV_LOG_ERROR, "Tone-set \"%.*s\" not defined\n",
964 tseq->name_len, tseq->name);
965 return AVERROR(EINVAL);
966 }
967 def = &s->def[i];
968 if (def->type == 'B') {
969 be = s->block_tseq + def->elements;
970 for (i = 0; i < def->nb_elements; i++) {
971 r = expand_tseq(log, s, nb_ev_max, t0, &be[i]);
972 if (r < 0)
973 return r;
974 }
975 } else {
976 ev = alloc_array_elem((void **)&s->events, sizeof(*ev),
977 &s->nb_events, nb_ev_max);
978 if (!ev)
979 return AVERROR(ENOMEM);
980 ev->ts = tseq->ts.t;
981 ev->elements = def->elements;
982 ev->nb_elements = def->nb_elements;
983 ev->fade = tseq->fade;
984 }
985 tseq->lock--;
986 return 0;
987 }
988
989 static int expand_script(void *log, struct sbg_script *s)
990 {
991 int i, r, nb_events_max = 0;
992
993 r = expand_timestamps(log, s);
994 if (r < 0)
995 return r;
996 for (i = 0; i < s->nb_tseq; i++) {
997 r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]);
998 if (r < 0)
999 return r;
1000 }
1001 if (!s->nb_events) {
1002 av_log(log, AV_LOG_ERROR, "No events in script\n");
1003 return AVERROR_INVALIDDATA;
1004 }
1005 if (s->opt_end_at_last)
1006 s->end_ts = s->events[s->nb_events - 1].ts;
1007 return 0;
1008 }
1009
1010 static int add_interval(struct ws_intervals *inter,
1011 enum ws_interval_type type, uint32_t channels, int ref,
1012 int64_t ts1, int32_t f1, int32_t a1,
1013 int64_t ts2, int32_t f2, int32_t a2)
1014 {
1015 struct ws_interval *i, *ri;
1016
1017 if (ref >= 0) {
1018 ri = &inter->inter[ref];
1019 /* ref and new intervals are constant, identical and adjacent */
1020 if (ri->type == type && ri->channels == channels &&
1021 ri->f1 == ri->f2 && ri->f2 == f1 && f1 == f2 &&
1022 ri->a1 == ri->a2 && ri->a2 == a1 && a1 == a2 &&
1023 ri->ts2 == ts1) {
1024 ri->ts2 = ts2;
1025 return ref;
1026 }
1027 }
1028 i = alloc_array_elem((void **)&inter->inter, sizeof(*i),
1029 &inter->nb_inter, &inter->max_inter);
1030 if (!i)
1031 return AVERROR(ENOMEM);
1032 i->ts1 = ts1;
1033 i->ts2 = ts2;
1034 i->type = type;
1035 i->channels = channels;
1036 i->f1 = f1;
1037 i->f2 = f2;
1038 i->a1 = a1;
1039 i->a2 = a2;
1040 i->phi = ref >= 0 ? ref | 0x80000000 : 0;
1041 return i - inter->inter;
1042 }
1043
1044 static int add_bell(struct ws_intervals *inter, struct sbg_script *s,
1045 int64_t ts1, int64_t ts2, int32_t f, int32_t a)
1046 {
1047 /* SBaGen uses an exponential decrease every 50ms.
1048 We approximate it with piecewise affine segments. */
1049 int32_t cpoints[][2] = {
1050 { 2, a },
1051 { 4, a - a / 4 },
1052 { 8, a / 2 },
1053 { 16, a / 4 },
1054 { 25, a / 10 },
1055 { 50, a / 80 },
1056 { 75, 0 },
1057 };
1058 int i, r;
1059 int64_t dt = s->sample_rate / 20, ts3 = ts1, ts4;
1060 for (i = 0; i < FF_ARRAY_ELEMS(cpoints); i++) {
1061 ts4 = FFMIN(ts2, ts1 + cpoints[i][0] * dt);
1062 r = add_interval(inter, WS_SINE, 3, -1,
1063 ts3, f, a, ts4, f, cpoints[i][1]);
1064 if (r < 0)
1065 return r;
1066 ts3 = ts4;
1067 a = cpoints[i][1];
1068 }
1069 return 0;
1070 }
1071
1072 static int generate_interval(void *log, struct sbg_script *s,
1073 struct ws_intervals *inter,
1074 int64_t ts1, int64_t ts2,
1075 struct sbg_script_synth *s1,
1076 struct sbg_script_synth *s2,
1077 int transition)
1078 {
1079 int r;
1080
1081 if (ts2 <= ts1 || (s1->vol == 0 && s2->vol == 0))
1082 return 0;
1083 switch (s1->type) {
1084 case SBG_TYPE_NONE:
1085 break;
1086 case SBG_TYPE_SINE:
1087 if (s1->beat == 0 && s2->beat == 0) {
1088 r = add_interval(inter, WS_SINE, 3, s1->ref.l,
1089 ts1, s1->carrier, s1->vol,
1090 ts2, s2->carrier, s2->vol);
1091 if (r < 0)
1092 return r;
1093 s2->ref.l = s2->ref.r = r;
1094 } else {
1095 r = add_interval(inter, WS_SINE, 1, s1->ref.l,
1096 ts1, s1->carrier + s1->beat / 2, s1->vol,
1097 ts2, s2->carrier + s2->beat / 2, s2->vol);
1098 if (r < 0)
1099 return r;
1100 s2->ref.l = r;
1101 r = add_interval(inter, WS_SINE, 2, s1->ref.r,
1102 ts1, s1->carrier - s1->beat / 2, s1->vol,
1103 ts2, s2->carrier - s2->beat / 2, s2->vol);
1104 if (r < 0)
1105 return r;
1106 s2->ref.r = r;
1107 }
1108 break;
1109
1110 case SBG_TYPE_BELL:
1111 if (transition == 2) {
1112 r = add_bell(inter, s, ts1, ts2, s1->carrier, s2->vol);
1113 if (r < 0)
1114 return r;
1115 }
1116 break;
1117
1118 case SBG_TYPE_SPIN:
1119 av_log(log, AV_LOG_WARNING, "Spinning noise not implemented, "
1120 "using pink noise instead.\n");
1121 /* fall through */
1122 case SBG_TYPE_NOISE:
1123 /* SBaGen's pink noise generator uses:
1124 - 1 band of white noise, mean square: 1/3;
1125 - 9 bands of subsampled white noise with linear
1126 interpolation, mean square: 2/3 each;
1127 with 1/10 weight each: the total mean square is 7/300.
1128 Our pink noise generator uses 8 bands of white noise with
1129 rectangular subsampling: the total mean square is 1/24.
1130 Therefore, to match SBaGen's volume, we must multiply vol by
1131 sqrt((7/300) / (1/24)) = sqrt(14/25) =~ 0.748
1132 */
1133 r = add_interval(inter, WS_NOISE, 3, s1->ref.l,
1134 ts1, 0, s1->vol - s1->vol / 4,
1135 ts2, 0, s2->vol - s2->vol / 4);
1136 if (r < 0)
1137 return r;
1138 s2->ref.l = s2->ref.r = r;
1139 break;
1140
1141 case SBG_TYPE_MIX:
1142 /* Unimplemented: silence; warning present elsewhere */
1143 default:
1144 av_log(log, AV_LOG_ERROR,
1145 "Type %d is not implemented\n", s1->type);
1146 return AVERROR_PATCHWELCOME;
1147 }
1148 return 0;
1149 }
1150
1151 static int generate_plateau(void *log, struct sbg_script *s,
1152 struct ws_intervals *inter,
1153 struct sbg_script_event *ev1)
1154 {
1155 int64_t ts1 = ev1->ts_int, ts2 = ev1->ts_trans;
1156 int i, r;
1157 struct sbg_script_synth *s1;
1158
1159 for (i = 0; i < ev1->nb_elements; i++) {
1160 s1 = &s->synth[ev1->elements + i];
1161 r = generate_interval(log, s, inter, ts1, ts2, s1, s1, 0);
1162 if (r < 0)
1163 return r;
1164 }
1165 return 0;
1166 }
1167
1168 /*
1169
1170 ts1 ts2 ts1 tsmid ts2
1171 | | | | |
1172 v v v | v
1173 ____ ____ v ____
1174 ''''.... ''.. ..''
1175 ''''....____ ''....''
1176
1177 compatible transition incompatible transition
1178 */
1179
1180 static int generate_transition(void *log, struct sbg_script *s,
1181 struct ws_intervals *inter,
1182 struct sbg_script_event *ev1,
1183 struct sbg_script_event *ev2)
1184 {
1185 int64_t ts1 = ev1->ts_trans, ts2 = ev1->ts_next;
1186 /* (ts1 + ts2) / 2 without overflow */
1187 int64_t tsmid = (ts1 >> 1) + (ts2 >> 1) + (ts1 & ts2 & 1);
1188 enum sbg_fade_type type = ev1->fade.slide | (ev1->fade.out & ev2->fade.in);
1189 int nb_elements = FFMAX(ev1->nb_elements, ev2->nb_elements);
1190 struct sbg_script_synth *s1, *s2, s1mod, s2mod, smid;
1191 int pass, i, r;
1192
1193 for (pass = 0; pass < 2; pass++) {
1194 /* pass = 0 -> compatible and first half of incompatible
1195 pass = 1 -> second half of incompatible
1196 Using two passes like that ensures that the intervals are generated
1197 in increasing order according to their start timestamp.
1198 Otherwise it would be necessary to sort them
1199 while keeping the mutual references.
1200 */
1201 for (i = 0; i < nb_elements; i++) {
1202 s1 = i < ev1->nb_elements ? &s->synth[ev1->elements + i] : &s1mod;
1203 s2 = i < ev2->nb_elements ? &s->synth[ev2->elements + i] : &s2mod;
1204 s1mod = s1 != &s1mod ? *s1 : (struct sbg_script_synth){ 0 };
1205 s2mod = s2 != &s2mod ? *s2 : (struct sbg_script_synth){ 0 };
1206 if (ev1->fade.slide) {
1207 /* for slides, and only for slides, silence ("-") is equivalent
1208 to anything with volume 0 */
1209 if (s1mod.type == SBG_TYPE_NONE) {
1210 s1mod = s2mod;
1211 s1mod.vol = 0;
1212 } else if (s2mod.type == SBG_TYPE_NONE) {
1213 s2mod = s1mod;
1214 s2mod.vol = 0;
1215 }
1216 }
1217 if (s1mod.type == s2mod.type &&
1218 s1mod.type != SBG_TYPE_BELL &&
1219 (type == SBG_FADE_ADAPT ||
1220 (s1mod.carrier == s2mod.carrier &&
1221 s1mod.beat == s2mod.beat))) {
1222 /* compatible: single transition */
1223 if (!pass) {
1224 r = generate_interval(log, s, inter,
1225 ts1, ts2, &s1mod, &s2mod, 3);
1226 if (r < 0)
1227 return r;
1228 s2->ref = s2mod.ref;
1229 }
1230 } else {
1231 /* incompatible: silence at midpoint */
1232 if (!pass) {
1233 smid = s1mod;
1234 smid.vol = 0;
1235 r = generate_interval(log, s, inter,
1236 ts1, tsmid, &s1mod, &smid, 1);
1237 if (r < 0)
1238 return r;
1239 } else {
1240 smid = s2mod;
1241 smid.vol = 0;
1242 r = generate_interval(log, s, inter,
1243 tsmid, ts2, &smid, &s2mod, 2);
1244 if (r < 0)
1245 return r;
1246 s2->ref = s2mod.ref;
1247 }
1248 }
1249 }
1250 }
1251 return 0;
1252 }
1253
1254 /*
1255 ev1 trats ev2 intts endts ev3
1256 | | | | | |
1257 v v v v v v
1258 ________________
1259 .... .... ....
1260 '''....________________....''' '''...._______________
1261
1262 \_________/\______________/\_________/\______________/\_________/\_____________/
1263 tr x->1 int1 tr 1->2 int2 tr 2->3 int3
1264 */
1265
1266 static int generate_intervals(void *log, struct sbg_script *s, int sample_rate,
1267 struct ws_intervals *inter)
1268 {
1269 int64_t trans_time = s->opt_fade_time / 2;
1270 struct sbg_script_event ev0, *ev1, *ev2;
1271 int64_t period;
1272 int i, r;
1273
1274 /* SBaGen handles the time before and after the extremal events,
1275 and the corresponding transitions, as if the sequence were cyclic
1276 with a 24-hours period. */
1277 period = s->events[s->nb_events - 1].ts - (uint64_t)s->events[0].ts;
1278 if (period < 0)
1279 return AVERROR_INVALIDDATA;
1280
1281 period = (period + (DAY_TS - 1)) / DAY_TS * DAY_TS;
1282 period = FFMAX(period, DAY_TS);
1283
1284 /* Prepare timestamps for transitions */
1285 for (i = 0; i < s->nb_events; i++) {
1286 ev1 = &s->events[i];
1287 ev2 = &s->events[(i + 1) % s->nb_events];
1288 ev1->ts_int = ev1->ts;
1289
1290 if (!ev1->fade.slide && ev1 >= ev2 && ev2->ts > INT64_MAX - period)
1291 return AVERROR_INVALIDDATA;
1292
1293 ev1->ts_trans = ev1->fade.slide ? ev1->ts
1294 : ev2->ts + (ev1 < ev2 ? 0 : period);
1295 }
1296 for (i = 0; i < s->nb_events; i++) {
1297 ev1 = &s->events[i];
1298 ev2 = &s->events[(i + 1) % s->nb_events];
1299 if (!ev1->fade.slide) {
1300 ev1->ts_trans = FFMAX(ev1->ts_int, ev1->ts_trans - trans_time);
1301 ev2->ts_int = FFMIN(ev2->ts_trans, ev2->ts_int + trans_time);
1302 }
1303 ev1->ts_next = ev2->ts_int + (ev1 < ev2 ? 0 : period);
1304 }
1305
1306 /* Pseudo event before the first one */
1307 ev0 = s->events[s->nb_events - 1];
1308 if (av_sat_sub64(ev0.ts_int, period) != (uint64_t)ev0.ts_int - period)
1309 return AVERROR_INVALIDDATA;
1310 ev0.ts_int -= period;
1311 ev0.ts_trans -= period;
1312 ev0.ts_next -= period;
1313
1314 /* Convert timestamps */
1315 for (i = -1; i < s->nb_events; i++) {
1316 ev1 = i < 0 ? &ev0 : &s->events[i];
1317 ev1->ts_int = av_rescale(ev1->ts_int, sample_rate, AV_TIME_BASE);
1318 ev1->ts_trans = av_rescale(ev1->ts_trans, sample_rate, AV_TIME_BASE);
1319 ev1->ts_next = av_rescale(ev1->ts_next, sample_rate, AV_TIME_BASE);
1320 }
1321
1322 /* Generate intervals */
1323 for (i = 0; i < s->nb_synth; i++)
1324 s->synth[i].ref.l = s->synth[i].ref.r = -1;
1325 for (i = -1; i < s->nb_events; i++) {
1326 ev1 = i < 0 ? &ev0 : &s->events[i];
1327 ev2 = &s->events[(i + 1) % s->nb_events];
1328 r = generate_plateau(log, s, inter, ev1);
1329 if (r < 0)
1330 return r;
1331 r = generate_transition(log, s, inter, ev1, ev2);
1332 if (r < 0)
1333 return r;
1334 }
1335 if (!inter->nb_inter)
1336 av_log(log, AV_LOG_WARNING, "Completely silent script.\n");
1337 return 0;
1338 }
1339
1340 static int encode_intervals(struct sbg_script *s, AVCodecParameters *par,
1341 struct ws_intervals *inter)
1342 {
1343 int i, edata_size = 4, ret;
1344 uint8_t *edata;
1345
1346 for (i = 0; i < inter->nb_inter; i++) {
1347 edata_size += inter->inter[i].type == WS_SINE ? 44 :
1348 inter->inter[i].type == WS_NOISE ? 32 : 0;
1349 if (edata_size < 0)
1350 return AVERROR(ENOMEM);
1351 }
1352 if ((ret = ff_alloc_extradata(par, edata_size)) < 0)
1353 return ret;
1354 edata = par->extradata;
1355
1356 #define ADD_EDATA32(v) do { AV_WL32(edata, (v)); edata += 4; } while(0)
1357 #define ADD_EDATA64(v) do { AV_WL64(edata, (v)); edata += 8; } while(0)
1358 ADD_EDATA32(inter->nb_inter);
1359 for (i = 0; i < inter->nb_inter; i++) {
1360 ADD_EDATA64(inter->inter[i].ts1);
1361 ADD_EDATA64(inter->inter[i].ts2);
1362 ADD_EDATA32(inter->inter[i].type);
1363 ADD_EDATA32(inter->inter[i].channels);
1364 switch (inter->inter[i].type) {
1365 case WS_SINE:
1366 ADD_EDATA32(inter->inter[i].f1);
1367 ADD_EDATA32(inter->inter[i].f2);
1368 ADD_EDATA32(inter->inter[i].a1);
1369 ADD_EDATA32(inter->inter[i].a2);
1370 ADD_EDATA32(inter->inter[i].phi);
1371 break;
1372 case WS_NOISE:
1373 ADD_EDATA32(inter->inter[i].a1);
1374 ADD_EDATA32(inter->inter[i].a2);
1375 break;
1376 }
1377 }
1378 if (edata != par->extradata + edata_size)
1379 return AVERROR_BUG;
1380 return 0;
1381 }
1382
1383 7467 static av_cold int sbg_read_probe(const AVProbeData *p)
1384 {
1385 int r, score;
1386 7467 struct sbg_script script = { 0 };
1387
1388 7467 r = parse_script(NULL, p->buf, p->buf_size, &script);
1389
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7467 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7467 score = r < 0 || !script.nb_def || !script.nb_tseq ? 0 :
1390 AVPROBE_SCORE_MAX / 3;
1391 7467 free_script(&script);
1392 7467 return score;
1393 }
1394
1395 static av_cold int sbg_read_header(AVFormatContext *avf)
1396 {
1397 struct sbg_demuxer *sbg = avf->priv_data;
1398 AVBPrint bprint;
1399 int r;
1400 struct sbg_script script = { 0 };
1401 AVStream *st;
1402 FFStream *sti;
1403 struct ws_intervals inter = { 0 };
1404
1405 av_bprint_init(&bprint, 0, sbg->max_file_size + 1U);
1406 r = read_whole_file(avf->pb, sbg->max_file_size, &bprint);
1407 if (r < 0)
1408 goto fail2;
1409
1410 r = parse_script(avf, bprint.str, bprint.len, &script);
1411 if (r < 0)
1412 goto fail2;
1413 if (!sbg->sample_rate)
1414 sbg->sample_rate = script.sample_rate;
1415 else
1416 script.sample_rate = sbg->sample_rate;
1417 if (!sbg->frame_size)
1418 sbg->frame_size = FFMAX(1, sbg->sample_rate / 10);
1419 if (script.opt_mix)
1420 av_log(avf, AV_LOG_WARNING, "Mix feature not implemented: "
1421 "-m is ignored and mix channels will be silent.\n");
1422 r = expand_script(avf, &script);
1423 if (r < 0)
1424 goto fail2;
1425 av_bprint_finalize(&bprint, NULL);
1426 r = generate_intervals(avf, &script, sbg->sample_rate, &inter);
1427 if (r < 0)
1428 goto fail;
1429
1430 if (script.end_ts != AV_NOPTS_VALUE && script.end_ts < script.start_ts) {
1431 r = AVERROR_INVALIDDATA;
1432 goto fail;
1433 }
1434
1435 st = avformat_new_stream(avf, NULL);
1436 if (!st) {
1437 r = AVERROR(ENOMEM);
1438 goto fail;
1439 }
1440 sti = ffstream(st);
1441 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
1442 st->codecpar->codec_id = AV_CODEC_ID_FFWAVESYNTH;
1443 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
1444 st->codecpar->sample_rate = sbg->sample_rate;
1445 st->codecpar->frame_size = sbg->frame_size;
1446 avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
1447 sti->probe_packets = 0;
1448 st->start_time = av_rescale(script.start_ts,
1449 sbg->sample_rate, AV_TIME_BASE);
1450 st->duration = script.end_ts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
1451 av_rescale(script.end_ts - script.start_ts,
1452 sbg->sample_rate, AV_TIME_BASE);
1453
1454 if (st->duration != AV_NOPTS_VALUE && (
1455 st->duration < 0 || st->start_time > INT64_MAX - st->duration)) {
1456 r = AVERROR_INVALIDDATA;
1457 goto fail;
1458 }
1459
1460 sti->cur_dts = st->start_time;
1461 r = encode_intervals(&script, st->codecpar, &inter);
1462 if (r < 0)
1463 goto fail;
1464
1465 av_free(inter.inter);
1466 free_script(&script);
1467 return 0;
1468
1469 fail2:
1470 av_bprint_finalize(&bprint, NULL);
1471 fail:
1472 av_free(inter.inter);
1473 free_script(&script);
1474 return r;
1475 }
1476
1477 static int sbg_read_packet(AVFormatContext *avf, AVPacket *packet)
1478 {
1479 int64_t ts, end_ts;
1480 int ret;
1481
1482 ts = ffstream(avf->streams[0])->cur_dts;
1483 end_ts = av_sat_add64(ts, avf->streams[0]->codecpar->frame_size);
1484 if (avf->streams[0]->duration != AV_NOPTS_VALUE)
1485 end_ts = FFMIN(avf->streams[0]->start_time + avf->streams[0]->duration,
1486 end_ts);
1487 if (end_ts <= ts)
1488 return AVERROR_EOF;
1489 if ((ret = av_new_packet(packet, 12)) < 0)
1490 return ret;
1491 packet->dts = packet->pts = ts;
1492 packet->duration = end_ts - ts;
1493 AV_WL64(packet->data + 0, ts);
1494 AV_WL32(packet->data + 8, packet->duration);
1495 return packet->size;
1496 }
1497
1498 static int sbg_read_seek2(AVFormatContext *avf, int stream_index,
1499 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
1500 {
1501 if (flags || stream_index > 0)
1502 return AVERROR(EINVAL);
1503 if (stream_index < 0)
1504 ts = av_rescale_q(ts, AV_TIME_BASE_Q, avf->streams[0]->time_base);
1505 ffstream(avf->streams[0])->cur_dts = ts;
1506 return 0;
1507 }
1508
1509 static int sbg_read_seek(AVFormatContext *avf, int stream_index,
1510 int64_t ts, int flags)
1511 {
1512 return sbg_read_seek2(avf, stream_index, ts, ts, ts, 0);
1513 }
1514
1515 static const AVOption sbg_options[] = {
1516 { "sample_rate", "", offsetof(struct sbg_demuxer, sample_rate),
1517 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1518 AV_OPT_FLAG_DECODING_PARAM },
1519 { "frame_size", "", offsetof(struct sbg_demuxer, frame_size),
1520 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1521 AV_OPT_FLAG_DECODING_PARAM },
1522 { "max_file_size", "", offsetof(struct sbg_demuxer, max_file_size),
1523 AV_OPT_TYPE_INT, { .i64 = 5000000 }, 0, INT_MAX,
1524 AV_OPT_FLAG_DECODING_PARAM },
1525 { NULL },
1526 };
1527
1528 static const AVClass sbg_demuxer_class = {
1529 .class_name = "sbg_demuxer",
1530 .item_name = av_default_item_name,
1531 .option = sbg_options,
1532 .version = LIBAVUTIL_VERSION_INT,
1533 };
1534
1535 const FFInputFormat ff_sbg_demuxer = {
1536 .p.name = "sbg",
1537 .p.long_name = NULL_IF_CONFIG_SMALL("SBaGen binaural beats script"),
1538 .p.extensions = "sbg",
1539 .p.priv_class = &sbg_demuxer_class,
1540 .priv_data_size = sizeof(struct sbg_demuxer),
1541 .read_probe = sbg_read_probe,
1542 .read_header = sbg_read_header,
1543 .read_packet = sbg_read_packet,
1544 .read_seek = sbg_read_seek,
1545 .read_seek2 = sbg_read_seek2,
1546 };
1547