FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/sbgdec.c
Date: 2026-05-01 13:04:54
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/attributes.h"
26 #include "libavutil/bprint.h"
27 #include "libavutil/channel_layout.h"
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/log.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/time_internal.h"
33 #include "avformat.h"
34 #include "demux.h"
35 #include "internal.h"
36
37 #define SBG_SCALE (1 << 16)
38 #define DAY (24 * 60 * 60)
39 #define DAY_TS ((int64_t)DAY * AV_TIME_BASE)
40
41 struct sbg_demuxer {
42 AVClass *class;
43 int sample_rate;
44 int frame_size;
45 int max_file_size;
46 };
47
48 struct sbg_string {
49 char *s;
50 char *e;
51 };
52
53 enum sbg_fade_type {
54 SBG_FADE_SILENCE = 0,
55 SBG_FADE_SAME = 1,
56 SBG_FADE_ADAPT = 3,
57 };
58
59 struct sbg_fade {
60 int8_t in, out, slide;
61 };
62
63 enum sbg_synth_type {
64 SBG_TYPE_NONE,
65 SBG_TYPE_SINE,
66 SBG_TYPE_NOISE,
67 SBG_TYPE_BELL,
68 SBG_TYPE_MIX,
69 SBG_TYPE_SPIN,
70 };
71
72 /* bell: freq constant, ampl decreases exponentially, can be approx lin */
73
74 struct sbg_timestamp {
75 int64_t t;
76 char type; /* 0 for relative, 'N' for now, 'T' for absolute */
77 };
78
79 struct sbg_script_definition {
80 char *name;
81 int name_len;
82 int elements, nb_elements;
83 char type; /* 'S' or 'B' */
84 };
85
86 struct sbg_script_synth {
87 int carrier;
88 int beat;
89 int vol;
90 enum sbg_synth_type type;
91 struct {
92 int l, r;
93 } ref;
94 };
95
96 struct sbg_script_tseq {
97 struct sbg_timestamp ts;
98 char *name;
99 int name_len;
100 int lock;
101 struct sbg_fade fade;
102 };
103
104 struct sbg_script_event {
105 int64_t ts;
106 int64_t ts_int, ts_trans, ts_next;
107 int elements, nb_elements;
108 struct sbg_fade fade;
109 };
110
111 struct sbg_script {
112 struct sbg_script_definition *def;
113 struct sbg_script_synth *synth;
114 struct sbg_script_tseq *tseq;
115 struct sbg_script_tseq *block_tseq;
116 struct sbg_script_event *events;
117 int nb_def;
118 int nb_tseq;
119 int nb_events;
120 int nb_synth;
121 int64_t start_ts;
122 int64_t end_ts;
123 int64_t opt_fade_time;
124 int64_t opt_duration;
125 char *opt_mix;
126 int sample_rate;
127 uint8_t opt_start_at_first;
128 uint8_t opt_end_at_last;
129 };
130
131 struct sbg_parser {
132 void *log;
133 char *script, *end;
134 char *cursor;
135 struct sbg_script scs;
136 struct sbg_timestamp current_time;
137 int nb_block_tseq;
138 int nb_def_max, nb_synth_max, nb_tseq_max, nb_block_tseq_max;
139 int line_no;
140 char err_msg[128];
141 };
142
143 enum ws_interval_type {
144 WS_SINE = MKTAG('S','I','N','E'),
145 WS_NOISE = MKTAG('N','O','I','S'),
146 };
147
148 struct ws_interval {
149 int64_t ts1, ts2;
150 enum ws_interval_type type;
151 uint32_t channels;
152 int32_t f1, f2;
153 int32_t a1, a2;
154 uint32_t phi;
155 };
156
157 struct ws_intervals {
158 struct ws_interval *inter;
159 int nb_inter;
160 int max_inter;
161 };
162
163 5 static void *alloc_array_elem(void **array, size_t elsize,
164 int *size, int *max_size)
165 {
166 void *ret;
167
168
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (*size == *max_size) {
169 5 int m = FFMAX(32, FFMIN(*max_size, INT_MAX / 2) * 2);
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (*size >= m)
171 return NULL;
172 5 *array = av_realloc_f(*array, m, elsize);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!*array)
174 return NULL;
175 5 *max_size = m;
176 }
177 5 ret = (char *)*array + elsize * *size;
178 5 memset(ret, 0, elsize);
179 5 (*size)++;
180 5 return ret;
181 }
182
183 7480 static int str_to_time(const char *str, int64_t *rtime)
184 {
185 7480 const char *cur = str;
186 char *end;
187 int hours, minutes;
188 7480 double seconds = 0;
189 7480 int64_t ts = 0;
190
191
4/4
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 5543 times.
✓ Branch 2 taken 1873 times.
✓ Branch 3 taken 64 times.
7480 if (*cur < '0' || *cur > '9')
192 7416 return 0;
193 64 hours = strtol(cur, &end, 10);
194
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')
195 60 return 0;
196 4 cur = end + 1;
197 4 minutes = strtol(cur, &end, 10);
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (end == cur)
199 return 0;
200 4 cur = end;
201
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (*end == ':'){
202 4 seconds = strtod(cur + 1, &end);
203
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (end > cur + 1)
204 4 cur = end;
205 4 ts = av_clipd(seconds * AV_TIME_BASE, INT64_MIN/2, INT64_MAX/2);
206 }
207 4 *rtime = av_sat_add64((hours * 3600LL + minutes * 60LL) * AV_TIME_BASE, ts);
208 4 return cur - str;
209 }
210
211 7637 static inline int is_space(char c)
212 {
213
6/6
✓ Branch 0 taken 7630 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7628 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7627 times.
7637 return c == ' ' || c == '\t' || c == '\r';
214 }
215
216 static inline int scale_double(void *log, double d, double m, int *r)
217 {
218 m *= d * SBG_SCALE;
219 if (m < INT_MIN || m >= INT_MAX) {
220 if (log)
221 av_log(log, AV_LOG_ERROR, "%g is too large\n", d);
222 return AVERROR(EDOM);
223 }
224 *r = m;
225 return 0;
226 }
227
228 7620 static int lex_space(struct sbg_parser *p)
229 {
230 7620 char *c = p->cursor;
231
232
3/4
✓ Branch 0 taken 7629 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 7620 times.
7629 while (p->cursor < p->end && is_space(*p->cursor))
233 9 p->cursor++;
234 7620 return p->cursor > c;
235 }
236
237 9378 static int lex_char(struct sbg_parser *p, char c)
238 {
239
3/4
✓ Branch 0 taken 9378 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 9364 times.
9378 int r = p->cursor < p->end && *p->cursor == c;
240
241 9378 p->cursor += r;
242 9378 return r;
243 }
244
245 4 static int lex_double(struct sbg_parser *p, double *r)
246 {
247 double d;
248 char *end;
249
250
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')
251 return 0;
252 4 d = strtod(p->cursor, &end);
253
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (end > p->cursor) {
254 2 *r = d;
255 2 p->cursor = end;
256 2 return 1;
257 }
258 2 return 0;
259 }
260
261 7489 static int lex_fixed(struct sbg_parser *p, const char *t, int l)
262 {
263
2/4
✓ Branch 0 taken 7489 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7489 times.
✗ Branch 3 not taken.
7489 if (p->end - p->cursor < l || memcmp(p->cursor, t, l))
264 7489 return 0;
265 p->cursor += l;
266 return 1;
267 }
268
269 15071 static int lex_line_end(struct sbg_parser *p)
270 {
271
3/4
✓ Branch 0 taken 15071 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 115 times.
✓ Branch 3 taken 14956 times.
15071 if (p->cursor < p->end && *p->cursor == '#') {
272 115 p->cursor++;
273
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')
274 11328 p->cursor++;
275 }
276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15071 times.
15071 if (p->cursor == p->end)
277 /* simulate final LF for files lacking it */
278 return 1;
279
2/2
✓ Branch 0 taken 14953 times.
✓ Branch 1 taken 118 times.
15071 if (*p->cursor != '\n')
280 14953 return 0;
281 118 p->cursor++;
282 118 p->line_no++;
283 118 lex_space(p);
284 118 return 1;
285 }
286
287 1 static int lex_wsword(struct sbg_parser *p, struct sbg_string *rs)
288 {
289 1 char *s = p->cursor, *c = s;
290
291
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')
292 return 0;
293
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))
294 3 c++;
295 1 rs->s = s;
296 1 rs->e = p->cursor = c;
297 1 lex_space(p);
298 1 return 1;
299 }
300
301 7483 static int lex_name(struct sbg_parser *p, struct sbg_string *rs)
302 {
303 7483 char *s = p->cursor, *c = s;
304
305
9/10
✓ Branch 0 taken 14957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
✓ Branch 3 taken 13838 times.
✓ Branch 4 taken 1071 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 6196 times.
✓ Branch 7 taken 7690 times.
✓ Branch 8 taken 6085 times.
✓ Branch 9 taken 111 times.
14957 while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
306
8/8
✓ Branch 0 taken 553 times.
✓ Branch 1 taken 7248 times.
✓ Branch 2 taken 270 times.
✓ Branch 3 taken 283 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 7498 times.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 7483 times.
7801 || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-'))
307 7474 c++;
308
2/2
✓ Branch 0 taken 5596 times.
✓ Branch 1 taken 1887 times.
7483 if (c == s)
309 5596 return 0;
310 1887 rs->s = s;
311 1887 rs->e = p->cursor = c;
312 1887 return 1;
313 }
314
315 7480 static int lex_time(struct sbg_parser *p, int64_t *rt)
316 {
317 7480 int r = str_to_time(p->cursor, rt);
318 7480 p->cursor += r;
319 7480 return r > 0;
320 }
321
322 #define FORWARD_ERROR(c) \
323 do { \
324 int errcode = c; \
325 if (errcode <= 0) \
326 return errcode ? errcode : AVERROR_INVALIDDATA; \
327 } while (0)
328
329 static int parse_immediate(struct sbg_parser *p)
330 {
331 snprintf(p->err_msg, sizeof(p->err_msg),
332 "immediate sequences not yet implemented");
333 return AVERROR_PATCHWELCOME;
334 }
335
336 static int parse_preprogrammed(struct sbg_parser *p)
337 {
338 snprintf(p->err_msg, sizeof(p->err_msg),
339 "preprogrammed sequences not yet implemented");
340 return AVERROR_PATCHWELCOME;
341 }
342
343 static int parse_optarg(struct sbg_parser *p, char o, struct sbg_string *r)
344 {
345 if (!lex_wsword(p, r)) {
346 snprintf(p->err_msg, sizeof(p->err_msg),
347 "option '%c' requires an argument", o);
348 return AVERROR_INVALIDDATA;
349 }
350 return 1;
351 }
352
353 7597 static int parse_options(struct sbg_parser *p)
354 {
355 struct sbg_string ostr, oarg;
356 7597 char mode = 0;
357 int r;
358 char *tptr;
359 double v;
360
361
3/4
✓ Branch 0 taken 7597 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7596 times.
✓ Branch 3 taken 1 times.
7597 if (p->cursor == p->end || *p->cursor != '-')
362 7596 return 0;
363
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)) {
364
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (; ostr.s < ostr.e; ostr.s++) {
365 1 char opt = *ostr.s;
366
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) {
367 case 'S':
368 p->scs.opt_start_at_first = 1;
369 break;
370 case 'E':
371 p->scs.opt_end_at_last = 1;
372 break;
373 case 'i':
374 mode = 'i';
375 break;
376 case 'p':
377 mode = 'p';
378 break;
379 case 'F':
380 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
381 v = strtod(oarg.s, &tptr);
382 if (oarg.e != tptr) {
383 snprintf(p->err_msg, sizeof(p->err_msg),
384 "syntax error for option -F");
385 return AVERROR_INVALIDDATA;
386 }
387 p->scs.opt_fade_time = v * AV_TIME_BASE / 1000;
388 break;
389 case 'L':
390 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
391 r = str_to_time(oarg.s, &p->scs.opt_duration);
392 if (oarg.e != oarg.s + r || p->scs.opt_duration < 0) {
393 snprintf(p->err_msg, sizeof(p->err_msg),
394 "syntax error for option -L");
395 return AVERROR_INVALIDDATA;
396 }
397 break;
398 case 'T':
399 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
400 r = str_to_time(oarg.s, &p->scs.start_ts);
401 if (oarg.e != oarg.s + r) {
402 snprintf(p->err_msg, sizeof(p->err_msg),
403 "syntax error for option -T");
404 return AVERROR_INVALIDDATA;
405 }
406 break;
407 case 'm':
408 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
409 tptr = av_malloc(oarg.e - oarg.s + 1);
410 if (!tptr)
411 return AVERROR(ENOMEM);
412 memcpy(tptr, oarg.s, oarg.e - oarg.s);
413 tptr[oarg.e - oarg.s] = 0;
414 av_free(p->scs.opt_mix);
415 p->scs.opt_mix = tptr;
416 break;
417 case 'q':
418 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
419 v = strtod(oarg.s, &tptr);
420 if (oarg.e != tptr) {
421 snprintf(p->err_msg, sizeof(p->err_msg),
422 "syntax error for option -q");
423 return AVERROR_INVALIDDATA;
424 }
425 if (v != 1) {
426 snprintf(p->err_msg, sizeof(p->err_msg),
427 "speed factor other than 1 not supported");
428 return AVERROR_PATCHWELCOME;
429 }
430 break;
431 case 'r':
432 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
433 r = strtol(oarg.s, &tptr, 10);
434 if (oarg.e != tptr) {
435 snprintf(p->err_msg, sizeof(p->err_msg),
436 "syntax error for option -r");
437 return AVERROR_INVALIDDATA;
438 }
439 if (r < 40) {
440 snprintf(p->err_msg, sizeof(p->err_msg),
441 "invalid sample rate");
442 return AVERROR_PATCHWELCOME;
443 }
444 p->scs.sample_rate = r;
445 break;
446 1 default:
447 1 snprintf(p->err_msg, sizeof(p->err_msg),
448 1 "unknown option: '%c'", *ostr.s);
449 1 return AVERROR_INVALIDDATA;
450 }
451 }
452 }
453 switch (mode) {
454 case 'i':
455 return parse_immediate(p);
456 case 'p':
457 return parse_preprogrammed(p);
458 case 0:
459 if (!lex_line_end(p))
460 return AVERROR_INVALIDDATA;
461 return 1;
462 }
463 return AVERROR_BUG;
464 }
465
466 7478 static int parse_timestamp(struct sbg_parser *p,
467 struct sbg_timestamp *rts, int64_t *rrel)
468 {
469 7478 int64_t abs = 0, rel = 0, dt;
470 7478 char type = 0;
471 int r;
472
473
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7478 times.
7478 if (lex_fixed(p, "NOW", 3)) {
474 type = 'N';
475 r = 1;
476 } else {
477 7478 r = lex_time(p, &abs);
478
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7474 times.
7478 if (r)
479 4 type = 'T';
480 }
481
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7476 times.
7478 while (lex_char(p, '+')) {
482
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_time(p, &dt))
483 2 return AVERROR_INVALIDDATA;
484 if (av_sat_add64(rel, dt) - dt != rel)
485 return AVERROR_INVALIDDATA;
486 rel += dt;
487 r = 1;
488 }
489
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7472 times.
7476 if (r) {
490
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if (!lex_space(p))
491 1 return AVERROR_INVALIDDATA;
492 3 rts->type = type;
493 3 rts->t = abs;
494 3 *rrel = rel;
495 }
496 7475 return r;
497 }
498
499 3 static int parse_fade(struct sbg_parser *p, struct sbg_fade *fr)
500 {
501 3 struct sbg_fade f = {0};
502
503
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (lex_char(p, '<'))
504 f.in = SBG_FADE_SILENCE;
505
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 else if (lex_char(p, '-'))
506 f.in = SBG_FADE_SAME;
507
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 else if (lex_char(p, '='))
508 f.in = SBG_FADE_ADAPT;
509 else
510 3 return 0;
511 if (lex_char(p, '>'))
512 f.out = SBG_FADE_SILENCE;
513 else if (lex_char(p, '-'))
514 f.out = SBG_FADE_SAME;
515 else if (lex_char(p, '='))
516 f.out = SBG_FADE_ADAPT;
517 else
518 return AVERROR_INVALIDDATA;
519 *fr = f;
520 return 1;
521 }
522
523 7478 static int parse_time_sequence(struct sbg_parser *p, int inblock)
524 {
525 struct sbg_timestamp ts;
526 int64_t rel_ts;
527 int r;
528 7478 struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 };
529 struct sbg_string name;
530 struct sbg_script_tseq *tseq;
531
532 7478 r = parse_timestamp(p, &ts, &rel_ts);
533
2/2
✓ Branch 0 taken 7472 times.
✓ Branch 1 taken 6 times.
7478 if (!r)
534 7472 return 0;
535
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (r < 0)
536 3 return r;
537
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ts.type) {
538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (inblock)
539 return AVERROR_INVALIDDATA;
540 3 p->current_time.type = ts.type;
541 3 p->current_time.t = ts.t;
542 } else if(!inblock && !p->current_time.type) {
543 snprintf(p->err_msg, sizeof(p->err_msg),
544 "relative time without previous absolute time");
545 return AVERROR_INVALIDDATA;
546 }
547 3 ts.type = p->current_time.type;
548
549
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)
550 return AVERROR_INVALIDDATA;
551 3 ts.t = p->current_time.t + rel_ts;
552 3 r = parse_fade(p, &fade);
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (r < 0)
554 return r;
555 3 lex_space(p);
556
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!lex_name(p, &name))
557 return AVERROR_INVALIDDATA;
558 3 lex_space(p);
559
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (lex_fixed(p, "->", 2)) {
560 fade.slide = SBG_FADE_ADAPT;
561 lex_space(p);
562 }
563
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
3 if (!lex_line_end(p))
564 2 return AVERROR_INVALIDDATA;
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 tseq = inblock ?
566 alloc_array_elem((void **)&p->scs.block_tseq, sizeof(*tseq),
567 &p->nb_block_tseq, &p->nb_block_tseq_max) :
568 1 alloc_array_elem((void **)&p->scs.tseq, sizeof(*tseq),
569 &p->scs.nb_tseq, &p->nb_tseq_max);
570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!tseq)
571 return AVERROR(ENOMEM);
572 1 tseq->ts = ts;
573 1 tseq->name = name.s;
574 1 tseq->name_len = name.e - name.s;
575 1 tseq->fade = fade;
576 1 return 1;
577 }
578
579 static int parse_wave_def(struct sbg_parser *p, int wavenum)
580 {
581 snprintf(p->err_msg, sizeof(p->err_msg),
582 "waveform definitions not yet implemented");
583 return AVERROR_PATCHWELCOME;
584 }
585
586 static int parse_block_def(struct sbg_parser *p,
587 struct sbg_script_definition *def)
588 {
589 int r, tseq;
590
591 lex_space(p);
592 if (!lex_line_end(p))
593 return AVERROR_INVALIDDATA;
594 tseq = p->nb_block_tseq;
595 while (1) {
596 r = parse_time_sequence(p, 1);
597 if (r < 0)
598 return r;
599 if (!r)
600 break;
601 }
602 if (!lex_char(p, '}'))
603 return AVERROR_INVALIDDATA;
604 lex_space(p);
605 if (!lex_line_end(p))
606 return AVERROR_INVALIDDATA;
607 def->type = 'B';
608 def->elements = tseq;
609 def->nb_elements = p->nb_block_tseq - tseq;
610 if (!def->nb_elements)
611 return AVERROR_INVALIDDATA;
612 return 1;
613 }
614
615 2 static int parse_volume(struct sbg_parser *p, int *vol)
616 {
617 double v;
618
619
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_char(p, '/'))
620 2 return 0;
621 if (!lex_double(p, &v))
622 return AVERROR_INVALIDDATA;
623 if (scale_double(p->log, v, 0.01, vol))
624 return AVERROR(ERANGE);
625 return 1;
626 }
627
628 2 static int parse_synth_channel_sine(struct sbg_parser *p,
629 struct sbg_script_synth *synth)
630 {
631 double carrierf, beatf;
632 int carrier, beat, vol;
633
634
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!lex_double(p, &carrierf))
635 return 0;
636
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_double(p, &beatf))
637 2 beatf = 0;
638
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));
639 if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
640 scale_double(p->log, beatf, 1, &beat) < 0)
641 return AVERROR(EDOM);
642 synth->type = SBG_TYPE_SINE;
643 synth->carrier = carrier;
644 synth->beat = beat;
645 synth->vol = vol;
646 return 1;
647 }
648
649 2 static int parse_synth_channel_pink(struct sbg_parser *p,
650 struct sbg_script_synth *synth)
651 {
652 int vol;
653
654
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "pink", 4))
655 2 return 0;
656 FORWARD_ERROR(parse_volume(p, &vol));
657 synth->type = SBG_TYPE_NOISE;
658 synth->vol = vol;
659 return 1;
660 }
661
662 2 static int parse_synth_channel_bell(struct sbg_parser *p,
663 struct sbg_script_synth *synth)
664 {
665 double carrierf;
666 int carrier, vol;
667
668
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "bell", 4))
669 2 return 0;
670 if (!lex_double(p, &carrierf))
671 return AVERROR_INVALIDDATA;
672 FORWARD_ERROR(parse_volume(p, &vol));
673 if (scale_double(p->log, carrierf, 1, &carrier) < 0)
674 return AVERROR(EDOM);
675 synth->type = SBG_TYPE_BELL;
676 synth->carrier = carrier;
677 synth->vol = vol;
678 return 1;
679 }
680
681 2 static int parse_synth_channel_mix(struct sbg_parser *p,
682 struct sbg_script_synth *synth)
683 {
684 int vol;
685
686
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "mix", 3))
687 2 return 0;
688 FORWARD_ERROR(parse_volume(p, &vol));
689 synth->type = SBG_TYPE_MIX;
690 synth->vol = vol;
691 return 1;
692 }
693
694 2 static int parse_synth_channel_spin(struct sbg_parser *p,
695 struct sbg_script_synth *synth)
696 {
697 double carrierf, beatf;
698 int carrier, beat, vol;
699
700
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!lex_fixed(p, "spin:", 5))
701 2 return 0;
702 if (!lex_double(p, &carrierf))
703 return AVERROR_INVALIDDATA;
704 if (!lex_double(p, &beatf))
705 return AVERROR_INVALIDDATA;
706 FORWARD_ERROR(parse_volume(p, &vol));
707 if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
708 scale_double(p->log, beatf, 1, &beat) < 0)
709 return AVERROR(EDOM);
710 synth->type = SBG_TYPE_SPIN;
711 synth->carrier = carrier;
712 synth->beat = beat;
713 synth->vol = vol;
714 return 1;
715 }
716
717 2 static int parse_synth_channel(struct sbg_parser *p)
718 {
719 int r;
720 struct sbg_script_synth *synth;
721
722 2 synth = alloc_array_elem((void **)&p->scs.synth, sizeof(*synth),
723 &p->scs.nb_synth, &p->nb_synth_max);
724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!synth)
725 return AVERROR(ENOMEM);
726 2 r = lex_char(p, '-');
727
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
728 2 r = parse_synth_channel_pink(p, synth);
729
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
730 2 r = parse_synth_channel_bell(p, synth);
731
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
732 2 r = parse_synth_channel_mix(p, synth);
733
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
734 2 r = parse_synth_channel_spin(p, synth);
735 /* Unimplemented: wave%d:%f%f/vol (carrier, beat) */
736
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!r)
737 2 r = parse_synth_channel_sine(p, synth);
738
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (r <= 0)
739 2 p->scs.nb_synth--;
740 2 return r;
741 }
742
743 2 static int parse_synth_def(struct sbg_parser *p,
744 struct sbg_script_definition *def)
745 {
746 int r, synth;
747
748 2 synth = p->scs.nb_synth;
749 while (1) {
750 2 r = parse_synth_channel(p);
751
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (r < 0)
752 2 return r;
753 if (!r || !lex_space(p))
754 break;
755 }
756 lex_space(p);
757 if (synth == p->scs.nb_synth)
758 return AVERROR_INVALIDDATA;
759 if (!lex_line_end(p))
760 return AVERROR_INVALIDDATA;
761 def->type = 'S';
762 def->elements = synth;
763 def->nb_elements = p->scs.nb_synth - synth;
764 return 1;
765 }
766
767 7480 static int parse_named_def(struct sbg_parser *p)
768 {
769 7480 char *cursor_save = p->cursor;
770 struct sbg_string name;
771 struct sbg_script_definition *def;
772
773
6/6
✓ Branch 1 taken 1884 times.
✓ Branch 2 taken 5596 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 1873 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 2 times.
7480 if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) {
774 7478 p->cursor = cursor_save;
775 7478 return 0;
776 }
777
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) &&
778 name.s[4] >= '0' && name.s[4] <= '9' &&
779 name.s[5] >= '0' && name.s[5] <= '9') {
780 int wavenum = (name.s[4] - '0') * 10 + (name.s[5] - '0');
781 return parse_wave_def(p, wavenum);
782 }
783 2 def = alloc_array_elem((void **)&p->scs.def, sizeof(*def),
784 &p->scs.nb_def, &p->nb_def_max);
785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!def)
786 return AVERROR(ENOMEM);
787 2 def->name = name.s;
788 2 def->name_len = name.e - name.s;
789
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (lex_char(p, '{'))
790 return parse_block_def(p, def);
791 2 return parse_synth_def(p, def);
792 }
793
794 14960 static void free_script(struct sbg_script *s)
795 {
796 14960 av_freep(&s->def);
797 14960 av_freep(&s->synth);
798 14960 av_freep(&s->tseq);
799 14960 av_freep(&s->block_tseq);
800 14960 av_freep(&s->events);
801 14960 av_freep(&s->opt_mix);
802 14960 }
803
804 7480 static int parse_script(void *log, char *script, int script_len,
805 struct sbg_script *rscript)
806 {
807 7480 struct sbg_parser sp = {
808 .log = log,
809 .script = script,
810 7480 .end = script + script_len,
811 .cursor = script,
812 .line_no = 1,
813 .err_msg = "",
814 .scs = {
815 /* default values */
816 .start_ts = AV_NOPTS_VALUE,
817 .sample_rate = 44100,
818 .opt_fade_time = 60 * AV_TIME_BASE,
819 },
820 };
821 int r;
822
823 7480 lex_space(&sp);
824
1/2
✓ Branch 0 taken 7597 times.
✗ Branch 1 not taken.
15077 while (sp.cursor < sp.end) {
825 7597 r = parse_options(&sp);
826
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7596 times.
7597 if (r < 0)
827 1 goto fail;
828
3/4
✓ Branch 0 taken 7596 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7479 times.
✓ Branch 4 taken 117 times.
7596 if (!r && !lex_line_end(&sp))
829 7479 break;
830 }
831
1/2
✓ Branch 0 taken 7480 times.
✗ Branch 1 not taken.
7480 while (sp.cursor < sp.end) {
832 7480 r = parse_named_def(&sp);
833
2/2
✓ Branch 0 taken 7478 times.
✓ Branch 1 taken 2 times.
7480 if (!r)
834 7478 r = parse_time_sequence(&sp, 0);
835
2/2
✓ Branch 0 taken 7472 times.
✓ Branch 1 taken 8 times.
7480 if (!r)
836
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7472 times.
7472 r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA;
837
2/2
✓ Branch 0 taken 7479 times.
✓ Branch 1 taken 1 times.
7480 if (r < 0)
838 7479 goto fail;
839 }
840 *rscript = sp.scs;
841 return 1;
842 7480 fail:
843 7480 free_script(&sp.scs);
844
2/2
✓ Branch 0 taken 7479 times.
✓ Branch 1 taken 1 times.
7480 if (!*sp.err_msg)
845
1/2
✓ Branch 0 taken 7479 times.
✗ Branch 1 not taken.
7479 if (r == AVERROR_INVALIDDATA)
846 7479 snprintf(sp.err_msg, sizeof(sp.err_msg), "syntax error");
847
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7480 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7480 if (log && *sp.err_msg) {
848 const char *ctx = sp.cursor;
849 const char *ectx = av_x_if_null(memchr(ctx, '\n', sp.end - sp.cursor),
850 sp.end);
851 int lctx = ectx - ctx;
852 const char *quote = "\"";
853 if (lctx > 0 && ctx[lctx - 1] == '\r')
854 lctx--;
855 if (lctx == 0) {
856 ctx = "the end of line";
857 lctx = strlen(ctx);
858 quote = "";
859 }
860 av_log(log, AV_LOG_ERROR, "Error line %d: %s near %s%.*s%s.\n",
861 sp.line_no, sp.err_msg, quote, lctx, ctx, quote);
862 }
863 7480 return r;
864 }
865
866 static int read_whole_file(AVIOContext *io, int max_size, AVBPrint *rbuf)
867 {
868 int ret = avio_read_to_bprint(io, rbuf, max_size);
869 if (ret < 0)
870 return ret;
871 if (!av_bprint_is_complete(rbuf))
872 return AVERROR(ENOMEM);
873 /* Check if we have read the whole file. AVIOContext.eof_reached is only
874 * set after a read failed due to EOF, so this check is incorrect in case
875 * max_size equals the actual file size, but checking for that would
876 * require attempting to read beyond max_size. */
877 if (!io->eof_reached)
878 return AVERROR(EFBIG);
879 return 0;
880 }
881
882 static int expand_timestamps(void *log, struct sbg_script *s)
883 {
884 int i, nb_rel = 0;
885 int64_t now, cur_ts, delta = 0;
886
887 for (i = 0; i < s->nb_tseq; i++)
888 nb_rel += s->tseq[i].ts.type == 'N';
889 if (nb_rel == s->nb_tseq) {
890 /* All ts are relative to NOW: consider NOW = 0 */
891 now = 0;
892 if (s->start_ts != AV_NOPTS_VALUE)
893 av_log(log, AV_LOG_WARNING,
894 "Start time ignored in a purely relative script.\n");
895 } else if (nb_rel == 0 && s->start_ts != AV_NOPTS_VALUE ||
896 s->opt_start_at_first) {
897 /* All ts are absolute and start time is specified */
898 if (s->start_ts == AV_NOPTS_VALUE)
899 s->start_ts = s->tseq[0].ts.t;
900 now = s->start_ts;
901 } else {
902 /* Mixed relative/absolute ts: expand */
903 time_t now0;
904 struct tm *tm, tmpbuf;
905
906 av_log(log, AV_LOG_WARNING,
907 "Scripts with mixed absolute and relative timestamps can give "
908 "unexpected results (pause, seeking, time zone change).\n");
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 av_fallthrough;
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 7480 static av_cold int sbg_read_probe(const AVProbeData *p)
1385 {
1386 int r, score;
1387 7480 struct sbg_script script = { 0 };
1388
1389 7480 r = parse_script(NULL, p->buf, p->buf_size, &script);
1390
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7480 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7480 score = r < 0 || !script.nb_def || !script.nb_tseq ? 0 :
1391 AVPROBE_SCORE_MAX / 3;
1392 7480 free_script(&script);
1393 7480 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 r = AVERROR(ENOMEM);
1439 goto fail;
1440 }
1441 sti = ffstream(st);
1442 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
1443 st->codecpar->codec_id = AV_CODEC_ID_FFWAVESYNTH;
1444 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
1445 st->codecpar->sample_rate = sbg->sample_rate;
1446 st->codecpar->frame_size = sbg->frame_size;
1447 avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
1448 sti->probe_packets = 0;
1449 st->start_time = av_rescale(script.start_ts,
1450 sbg->sample_rate, AV_TIME_BASE);
1451 st->duration = script.end_ts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
1452 av_rescale(script.end_ts - script.start_ts,
1453 sbg->sample_rate, AV_TIME_BASE);
1454
1455 if (st->duration != AV_NOPTS_VALUE && (
1456 st->duration < 0 || st->start_time > INT64_MAX - st->duration)) {
1457 r = AVERROR_INVALIDDATA;
1458 goto fail;
1459 }
1460
1461 sti->cur_dts = st->start_time;
1462 r = encode_intervals(&script, st->codecpar, &inter);
1463 if (r < 0)
1464 goto fail;
1465
1466 av_free(inter.inter);
1467 free_script(&script);
1468 return 0;
1469
1470 fail2:
1471 av_bprint_finalize(&bprint, NULL);
1472 fail:
1473 av_free(inter.inter);
1474 free_script(&script);
1475 return r;
1476 }
1477
1478 static int sbg_read_packet(AVFormatContext *avf, AVPacket *packet)
1479 {
1480 int64_t ts, end_ts;
1481 int ret;
1482
1483 ts = ffstream(avf->streams[0])->cur_dts;
1484 end_ts = av_sat_add64(ts, avf->streams[0]->codecpar->frame_size);
1485 if (avf->streams[0]->duration != AV_NOPTS_VALUE)
1486 end_ts = FFMIN(avf->streams[0]->start_time + avf->streams[0]->duration,
1487 end_ts);
1488 if (end_ts <= ts)
1489 return AVERROR_EOF;
1490 if ((ret = av_new_packet(packet, 12)) < 0)
1491 return ret;
1492 packet->dts = packet->pts = ts;
1493 packet->duration = end_ts - ts;
1494 AV_WL64(packet->data + 0, ts);
1495 AV_WL32(packet->data + 8, packet->duration);
1496 return packet->size;
1497 }
1498
1499 static int sbg_read_seek2(AVFormatContext *avf, int stream_index,
1500 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
1501 {
1502 if (flags || stream_index > 0)
1503 return AVERROR(EINVAL);
1504 if (stream_index < 0)
1505 ts = av_rescale_q(ts, AV_TIME_BASE_Q, avf->streams[0]->time_base);
1506 ffstream(avf->streams[0])->cur_dts = ts;
1507 return 0;
1508 }
1509
1510 static int sbg_read_seek(AVFormatContext *avf, int stream_index,
1511 int64_t ts, int flags)
1512 {
1513 return sbg_read_seek2(avf, stream_index, ts, ts, ts, 0);
1514 }
1515
1516 static const AVOption sbg_options[] = {
1517 { "sample_rate", "", offsetof(struct sbg_demuxer, sample_rate),
1518 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1519 AV_OPT_FLAG_DECODING_PARAM },
1520 { "frame_size", "", offsetof(struct sbg_demuxer, frame_size),
1521 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1522 AV_OPT_FLAG_DECODING_PARAM },
1523 { "max_file_size", "", offsetof(struct sbg_demuxer, max_file_size),
1524 AV_OPT_TYPE_INT, { .i64 = 5000000 }, 0, INT_MAX,
1525 AV_OPT_FLAG_DECODING_PARAM },
1526 { NULL },
1527 };
1528
1529 static const AVClass sbg_demuxer_class = {
1530 .class_name = "sbg_demuxer",
1531 .item_name = av_default_item_name,
1532 .option = sbg_options,
1533 .version = LIBAVUTIL_VERSION_INT,
1534 };
1535
1536 const FFInputFormat ff_sbg_demuxer = {
1537 .p.name = "sbg",
1538 .p.long_name = NULL_IF_CONFIG_SMALL("SBaGen binaural beats script"),
1539 .p.extensions = "sbg",
1540 .p.priv_class = &sbg_demuxer_class,
1541 .priv_data_size = sizeof(struct sbg_demuxer),
1542 .read_probe = sbg_read_probe,
1543 .read_header = sbg_read_header,
1544 .read_packet = sbg_read_packet,
1545 .read_seek = sbg_read_seek,
1546 .read_seek2 = sbg_read_seek2,
1547 };
1548