FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/sbgdec.c
Date: 2026-09-26 14:26:21
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 8071 static int str_to_time(const char *str, int64_t *rtime)
184 {
185 8071 const char *cur = str;
186 char *end;
187 int hours, minutes;
188 8071 double seconds = 0;
189 8071 int64_t ts = 0;
190
191
4/4
✓ Branch 0 taken 2086 times.
✓ Branch 1 taken 5985 times.
✓ Branch 2 taken 2018 times.
✓ Branch 3 taken 68 times.
8071 if (*cur < '0' || *cur > '9')
192 8003 return 0;
193 68 hours = strtol(cur, &end, 10);
194
5/8
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 64 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
68 if (end == cur || *end != ':' || end[1] < '0' || end[1] > '9')
195 64 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 8236 static inline int is_space(char c)
212 {
213
6/6
✓ Branch 0 taken 8228 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8226 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 8225 times.
8236 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 8218 static int lex_space(struct sbg_parser *p)
229 {
230 8218 char *c = p->cursor;
231
232
3/4
✓ Branch 0 taken 8228 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 8218 times.
8228 while (p->cursor < p->end && is_space(*p->cursor))
233 10 p->cursor++;
234 8218 return p->cursor > c;
235 }
236
237 10114 static int lex_char(struct sbg_parser *p, char c)
238 {
239
3/4
✓ Branch 0 taken 10114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 10100 times.
10114 int r = p->cursor < p->end && *p->cursor == c;
240
241 10114 p->cursor += r;
242 10114 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 8080 static int lex_fixed(struct sbg_parser *p, const char *t, int l)
262 {
263
2/4
✓ Branch 0 taken 8080 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8080 times.
✗ Branch 3 not taken.
8080 if (p->end - p->cursor < l || memcmp(p->cursor, t, l))
264 8080 return 0;
265 ✗ p->cursor += l;
266 ✗ return 1;
267 }
268
269 16260 static int lex_line_end(struct sbg_parser *p)
270 {
271
3/4
✓ Branch 0 taken 16260 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 122 times.
✓ Branch 3 taken 16138 times.
16260 if (p->cursor < p->end && *p->cursor == '#') {
272 122 p->cursor++;
273
3/4
✓ Branch 0 taken 11704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11582 times.
✓ Branch 3 taken 122 times.
11704 while (p->cursor < p->end && *p->cursor != '\n')
274 11582 p->cursor++;
275 }
276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16260 times.
16260 if (p->cursor == p->end)
277 /* simulate final LF for files lacking it */
278 ✗ return 1;
279
2/2
✓ Branch 0 taken 16135 times.
✓ Branch 1 taken 125 times.
16260 if (*p->cursor != '\n')
280 16135 return 0;
281 125 p->cursor++;
282 125 p->line_no++;
283 125 lex_space(p);
284 125 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 8074 static int lex_name(struct sbg_parser *p, struct sbg_string *rs)
302 {
303 8074 char *s = p->cursor, *c = s;
304
305
9/10
✓ Branch 0 taken 16058 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1290 times.
✓ Branch 3 taken 14768 times.
✓ Branch 4 taken 1238 times.
✓ Branch 5 taken 52 times.
✓ Branch 6 taken 6510 times.
✓ Branch 7 taken 8310 times.
✓ Branch 8 taken 6395 times.
✓ Branch 9 taken 115 times.
16058 while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
306
8/8
✓ Branch 0 taken 592 times.
✓ Branch 1 taken 7833 times.
✓ Branch 2 taken 301 times.
✓ Branch 3 taken 291 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 8091 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 8074 times.
8425 || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-'))
307 7984 c++;
308
2/2
✓ Branch 0 taken 6042 times.
✓ Branch 1 taken 2032 times.
8074 if (c == s)
309 6042 return 0;
310 2032 rs->s = s;
311 2032 rs->e = p->cursor = c;
312 2032 return 1;
313 }
314
315 8071 static int lex_time(struct sbg_parser *p, int64_t *rt)
316 {
317 8071 int r = str_to_time(p->cursor, rt);
318 8071 p->cursor += r;
319 8071 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 8195 static int parse_options(struct sbg_parser *p)
354 {
355 struct sbg_string ostr, oarg;
356 8195 char mode = 0;
357 int r;
358 char *tptr;
359 double v;
360
361
3/4
✓ Branch 0 taken 8195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8194 times.
✓ Branch 3 taken 1 times.
8195 if (p->cursor == p->end || *p->cursor != '-')
362 8194 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 8069 static int parse_timestamp(struct sbg_parser *p,
467 struct sbg_timestamp *rts, int64_t *rrel)
468 {
469 8069 int64_t abs = 0, rel = 0, dt;
470 8069 char type = 0;
471 int r;
472
473
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8069 times.
8069 if (lex_fixed(p, "NOW", 3)) {
474 ✗ type = 'N';
475 ✗ r = 1;
476 } else {
477 8069 r = lex_time(p, &abs);
478
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8065 times.
8069 if (r)
479 4 type = 'T';
480 }
481
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8067 times.
8069 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 8063 times.
8067 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 8066 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 8069 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 8069 struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 };
529 struct sbg_string name;
530 struct sbg_script_tseq *tseq;
531
532 8069 r = parse_timestamp(p, &ts, &rel_ts);
533
2/2
✓ Branch 0 taken 8063 times.
✓ Branch 1 taken 6 times.
8069 if (!r)
534 8063 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 8071 static int parse_named_def(struct sbg_parser *p)
768 {
769 8071 char *cursor_save = p->cursor;
770 struct sbg_string name;
771 struct sbg_script_definition *def;
772
773
6/6
✓ Branch 1 taken 2029 times.
✓ Branch 2 taken 6042 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 2018 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 2 times.
8071 if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) {
774 8069 p->cursor = cursor_save;
775 8069 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 16142 static void free_script(struct sbg_script *s)
795 {
796 16142 av_freep(&s->def);
797 16142 av_freep(&s->synth);
798 16142 av_freep(&s->tseq);
799 16142 av_freep(&s->block_tseq);
800 16142 av_freep(&s->events);
801 16142 av_freep(&s->opt_mix);
802 16142 }
803
804 8071 static int parse_script(void *log, char *script, int script_len,
805 struct sbg_script *rscript)
806 {
807 8071 struct sbg_parser sp = {
808 .log = log,
809 .script = script,
810 8071 .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 8071 lex_space(&sp);
824
1/2
✓ Branch 0 taken 8195 times.
✗ Branch 1 not taken.
16266 while (sp.cursor < sp.end) {
825 8195 r = parse_options(&sp);
826
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8194 times.
8195 if (r < 0)
827 1 goto fail;
828
3/4
✓ Branch 0 taken 8194 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8070 times.
✓ Branch 4 taken 124 times.
8194 if (!r && !lex_line_end(&sp))
829 8070 break;
830 }
831
1/2
✓ Branch 0 taken 8071 times.
✗ Branch 1 not taken.
8071 while (sp.cursor < sp.end) {
832 8071 r = parse_named_def(&sp);
833
2/2
✓ Branch 0 taken 8069 times.
✓ Branch 1 taken 2 times.
8071 if (!r)
834 8069 r = parse_time_sequence(&sp, 0);
835
2/2
✓ Branch 0 taken 8063 times.
✓ Branch 1 taken 8 times.
8071 if (!r)
836
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8063 times.
8063 r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA;
837
2/2
✓ Branch 0 taken 8070 times.
✓ Branch 1 taken 1 times.
8071 if (r < 0)
838 8070 goto fail;
839 }
840 ✗ *rscript = sp.scs;
841 ✗ return 1;
842 8071 fail:
843 8071 free_script(&sp.scs);
844
2/2
✓ Branch 0 taken 8070 times.
✓ Branch 1 taken 1 times.
8071 if (!*sp.err_msg)
845
1/2
✓ Branch 0 taken 8070 times.
✗ Branch 1 not taken.
8070 if (r == AVERROR_INVALIDDATA)
846 8070 snprintf(sp.err_msg, sizeof(sp.err_msg), "syntax error");
847
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8071 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8071 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 8071 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 8071 static av_cold int sbg_read_probe(const AVProbeData *p)
1385 {
1386 int r, score;
1387 8071 struct sbg_script script = { 0 };
1388
1389 8071 r = parse_script(NULL, p->buf, p->buf_size, &script);
1390
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8071 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8071 score = r < 0 || !script.nb_def || !script.nb_tseq ? 0 :
1391 AVPROBE_SCORE_MAX / 3;
1392 8071 free_script(&script);
1393 8071 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