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