tools/sofa2wavs: fix build on Windows
[ffmpeg.git] / libavformat / tee.c
1 /*
2 * Tee pseudo-muxer
3 * Copyright (c) 2012 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 License
9 * 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
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with FFmpeg; if not, write to the Free Software * Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23 #include "libavutil/avutil.h"
24 #include "libavutil/avstring.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavcodec/bsf.h"
28 #include "internal.h"
29 #include "avformat.h"
30 #include "mux.h"
31 #include "tee_common.h"
32
33 typedef enum {
34 ON_SLAVE_FAILURE_ABORT = 1,
35 ON_SLAVE_FAILURE_IGNORE = 2
36 } SlaveFailurePolicy;
37
38 #define DEFAULT_SLAVE_FAILURE_POLICY ON_SLAVE_FAILURE_ABORT
39
40 typedef struct {
41 AVFormatContext *avf;
42 AVBSFContext **bsfs; ///< bitstream filters per stream
43
44 SlaveFailurePolicy on_fail;
45 int use_fifo;
46 AVDictionary *fifo_options;
47
48 /** map from input to output streams indexes,
49 * disabled output streams are set to -1 */
50 int *stream_map;
51 int header_written;
52 } TeeSlave;
53
54 typedef struct TeeContext {
55 const AVClass *class;
56 unsigned nb_slaves;
57 unsigned nb_alive;
58 TeeSlave *slaves;
59 int use_fifo;
60 AVDictionary *fifo_options;
61 } TeeContext;
62
63 static const char *const slave_delim = "|";
64 static const char *const slave_bsfs_spec_sep = "/";
65 static const char *const slave_select_sep = ",";
66
67 #define OFFSET(x) offsetof(TeeContext, x)
68 static const AVOption options[] = {
69 {"use_fifo", "Use fifo pseudo-muxer to separate actual muxers from encoder",
70 OFFSET(use_fifo), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
71 {"fifo_options", "fifo pseudo-muxer options", OFFSET(fifo_options),
72 AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM},
73 {NULL}
74 };
75
76 static const AVClass tee_muxer_class = {
77 .class_name = "Tee muxer",
78 .item_name = av_default_item_name,
79 .option = options,
80 .version = LIBAVUTIL_VERSION_INT,
81 };
82
83 static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *tee_slave)
84 {
85 if (!opt) {
86 tee_slave->on_fail = DEFAULT_SLAVE_FAILURE_POLICY;
87 return 0;
88 } else if (!av_strcasecmp("abort", opt)) {
89 tee_slave->on_fail = ON_SLAVE_FAILURE_ABORT;
90 return 0;
91 } else if (!av_strcasecmp("ignore", opt)) {
92 tee_slave->on_fail = ON_SLAVE_FAILURE_IGNORE;
93 return 0;
94 }
95 /* Set failure behaviour to abort, so invalid option error will not be ignored */
96 tee_slave->on_fail = ON_SLAVE_FAILURE_ABORT;
97 return AVERROR(EINVAL);
98 }
99
100 static int parse_slave_fifo_policy(const char *use_fifo, TeeSlave *tee_slave)
101 {
102 /*TODO - change this to use proper function for parsing boolean
103 * options when there is one */
104 if (av_match_name(use_fifo, "true,y,yes,enable,enabled,on,1")) {
105 tee_slave->use_fifo = 1;
106 } else if (av_match_name(use_fifo, "false,n,no,disable,disabled,off,0")) {
107 tee_slave->use_fifo = 0;
108 } else {
109 return AVERROR(EINVAL);
110 }
111 return 0;
112 }
113
114 static int parse_slave_fifo_options(const char *fifo_options, TeeSlave *tee_slave)
115 {
116 return av_dict_parse_string(&tee_slave->fifo_options, fifo_options, "=", ":", 0);
117 }
118
119 static int close_slave(TeeSlave *tee_slave)
120 {
121 AVFormatContext *avf;
122 int ret = 0;
123
124 av_dict_free(&tee_slave->fifo_options);
125 avf = tee_slave->avf;
126 if (!avf)
127 return 0;
128
129 if (tee_slave->header_written)
130 ret = av_write_trailer(avf);
131
132 if (tee_slave->bsfs) {
133 for (unsigned i = 0; i < avf->nb_streams; ++i)
134 av_bsf_free(&tee_slave->bsfs[i]);
135 }
136 av_freep(&tee_slave->stream_map);
137 av_freep(&tee_slave->bsfs);
138
139 ff_format_io_close(avf, &avf->pb);
140 avformat_free_context(avf);
141 tee_slave->avf = NULL;
142 return ret;
143 }
144
145 static void close_slaves(AVFormatContext *avf)
146 {
147 TeeContext *tee = avf->priv_data;
148
149 for (unsigned i = 0; i < tee->nb_slaves; i++) {
150 close_slave(&tee->slaves[i]);
151 }
152 av_freep(&tee->slaves);
153 }
154
155 static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
156 {
157 int ret;
158 AVDictionary *options = NULL, *bsf_options = NULL;
159 const AVDictionaryEntry *entry;
160 char *filename;
161 char *format = NULL, *select = NULL;
162 AVFormatContext *avf2 = NULL;
163 int stream_count;
164 int fullret;
165 char *subselect = NULL, *next_subselect = NULL, *first_subselect = NULL, *tmp_select = NULL;
166
167 if ((ret = ff_tee_parse_slave_options(avf, slave, &options, &filename)) < 0)
168 return ret;
169
170 tee_slave->on_fail = DEFAULT_SLAVE_FAILURE_POLICY;
171
172 #define CONSUME_OPTION(option, field, action) do { \
173 AVDictionaryEntry *en = av_dict_get(options, option, NULL, 0); \
174 if (en) { \
175 field = en->value; \
176 { action } \
177 av_dict_set(&options, option, NULL, 0); \
178 } \
179 } while (0)
180 #define STEAL_OPTION(option, field) \
181 CONSUME_OPTION(option, field, \
182 en->value = NULL; /* prevent it from being freed */)
183 #define PROCESS_OPTION(option, function, on_error) do { \
184 const char *value; \
185 CONSUME_OPTION(option, value, if ((ret = function) < 0) \
186 { { on_error } goto end; }); \
187 } while (0)
188
189 STEAL_OPTION("f", format);
190 STEAL_OPTION("select", select);
191 PROCESS_OPTION("onfail",
192 parse_slave_failure_policy_option(value, tee_slave),
193 av_log(avf, AV_LOG_ERROR, "Invalid onfail option value, "
194 "valid options are 'abort' and 'ignore'\n"););
195 PROCESS_OPTION("use_fifo",
196 parse_slave_fifo_policy(value, tee_slave),
197 av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n",
198 av_err2str(ret)););
199 PROCESS_OPTION("fifo_options",
200 parse_slave_fifo_options(value, tee_slave), ;);
201 entry = NULL;
202 while ((entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX))) {
203 /* trim out strlen("bsfs") characters from key */
204 av_dict_set(&bsf_options, entry->key + 4, entry->value, 0);
205 av_dict_set(&options, entry->key, NULL, 0);
206 }
207
208 if (tee_slave->use_fifo) {
209
210 if (options) {
211 char *format_options_str = NULL;
212 ret = av_dict_get_string(options, &format_options_str, '=', ':');
213 if (ret < 0)
214 goto end;
215
216 ret = av_dict_set(&tee_slave->fifo_options, "format_opts", format_options_str,
217 AV_DICT_DONT_STRDUP_VAL);
218 if (ret < 0)
219 goto end;
220 }
221
222 if (format) {
223 ret = av_dict_set(&tee_slave->fifo_options, "fifo_format", format,
224 AV_DICT_DONT_STRDUP_VAL);
225 format = NULL;
226 if (ret < 0)
227 goto end;
228 }
229
230 av_dict_free(&options);
231 options = tee_slave->fifo_options;
232 tee_slave->fifo_options = NULL;
233 }
234 ret = avformat_alloc_output_context2(&avf2, NULL,
235 tee_slave->use_fifo ? "fifo" :format, filename);
236 if (ret < 0)
237 goto end;
238 tee_slave->avf = avf2;
239 av_dict_copy(&avf2->metadata, avf->metadata, 0);
240 avf2->opaque = avf->opaque;
241 avf2->io_open = avf->io_open;
242 avf2->io_close2 = avf->io_close2;
243 avf2->interrupt_callback = avf->interrupt_callback;
244 avf2->flags = avf->flags;
245 avf2->strict_std_compliance = avf->strict_std_compliance;
246
247 tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map));
248 if (!tee_slave->stream_map) {
249 ret = AVERROR(ENOMEM);
250 goto end;
251 }
252
253 stream_count = 0;
254 for (unsigned i = 0; i < avf->nb_streams; i++) {
255 const AVStream *st = avf->streams[i];
256 AVStream *st2;
257 if (select) {
258 tmp_select = av_strdup(select); // av_strtok is destructive so we regenerate it in each loop
259 if (!tmp_select) {
260 ret = AVERROR(ENOMEM);
261 goto end;
262 }
263 fullret = 0;
264 first_subselect = tmp_select;
265 next_subselect = NULL;
266 while (subselect = av_strtok(first_subselect, slave_select_sep, &next_subselect)) {
267 first_subselect = NULL;
268
269 ret = avformat_match_stream_specifier(avf, avf->streams[i], subselect);
270 if (ret < 0) {
271 av_log(avf, AV_LOG_ERROR,
272 "Invalid stream specifier '%s' for output '%s'\n",
273 subselect, slave);
274 goto end;
275 }
276 if (ret != 0) {
277 fullret = 1; // match
278 break;
279 }
280 }
281 av_freep(&tmp_select);
282
283 if (fullret == 0) { /* no match */
284 tee_slave->stream_map[i] = -1;
285 continue;
286 }
287 }
288 tee_slave->stream_map[i] = stream_count++;
289
290 st2 = ff_stream_clone(avf2, st);
291 if (!st2) {
292 ret = AVERROR(ENOMEM);
293 goto end;
294 }
295 }
296
297 ret = ff_format_output_open(avf2, filename, &options);
298 if (ret < 0) {
299 av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n", slave,
300 av_err2str(ret));
301 goto end;
302 }
303
304 if ((ret = avformat_write_header(avf2, &options)) < 0) {
305 av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n",
306 slave, av_err2str(ret));
307 goto end;
308 }
309 tee_slave->header_written = 1;
310
311 tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(*tee_slave->bsfs));
312 if (!tee_slave->bsfs) {
313 ret = AVERROR(ENOMEM);
314 goto end;
315 }
316
317 entry = NULL;
318 while (entry = av_dict_iterate(bsf_options, NULL)) {
319 const char *spec = entry->key;
320 if (*spec) {
321 if (strspn(spec, slave_bsfs_spec_sep) != 1) {
322 av_log(avf, AV_LOG_ERROR,
323 "Specifier separator in '%s' is '%c', but only characters '%s' "
324 "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep);
325 ret = AVERROR(EINVAL);
326 goto end;
327 }
328 spec++; /* consume separator */
329 }
330
331 for (unsigned i = 0; i < avf2->nb_streams; i++) {
332 ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec);
333 if (ret < 0) {
334 av_log(avf, AV_LOG_ERROR,
335 "Invalid stream specifier '%s' in bsfs option '%s' for slave "
336 "output '%s'\n", spec, entry->key, filename);
337 goto end;
338 }
339
340 if (ret > 0) {
341 av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave "
342 "output '%s'\n", spec, entry->value, i, filename);
343 if (tee_slave->bsfs[i]) {
344 av_log(avf, AV_LOG_WARNING,
345 "Duplicate bsfs specification associated to stream %d of slave "
346 "output '%s', filters will be ignored\n", i, filename);
347 continue;
348 }
349 ret = av_bsf_list_parse_str(entry->value, &tee_slave->bsfs[i]);
350 if (ret < 0) {
351 av_log(avf, AV_LOG_ERROR,
352 "Error parsing bitstream filter sequence '%s' associated to "
353 "stream %d of slave output '%s'\n", entry->value, i, filename);
354 goto end;
355 }
356 }
357 }
358
359 av_dict_set(&bsf_options, entry->key, NULL, 0);
360 }
361
362 for (unsigned i = 0; i < avf->nb_streams; i++){
363 int target_stream = tee_slave->stream_map[i];
364 if (target_stream < 0)
365 continue;
366
367 if (!tee_slave->bsfs[target_stream]) {
368 /* Add pass-through bitstream filter */
369 ret = av_bsf_get_null_filter(&tee_slave->bsfs[target_stream]);
370 if (ret < 0) {
371 av_log(avf, AV_LOG_ERROR,
372 "Failed to create pass-through bitstream filter: %s\n",
373 av_err2str(ret));
374 goto end;
375 }
376 }
377
378 tee_slave->bsfs[target_stream]->time_base_in = avf->streams[i]->time_base;
379 ret = avcodec_parameters_copy(tee_slave->bsfs[target_stream]->par_in,
380 avf->streams[i]->codecpar);
381 if (ret < 0)
382 goto end;
383
384 ret = av_bsf_init(tee_slave->bsfs[target_stream]);
385 if (ret < 0) {
386 av_log(avf, AV_LOG_ERROR,
387 "Failed to initialize bitstream filter(s): %s\n",
388 av_err2str(ret));
389 goto end;
390 }
391 }
392
393 if (options) {
394 entry = NULL;
395 while ((entry = av_dict_iterate(options, entry)))
396 av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
397 ret = AVERROR_OPTION_NOT_FOUND;
398 goto end;
399 }
400
401 end:
402 av_free(format);
403 av_free(select);
404 av_dict_free(&options);
405 av_dict_free(&bsf_options);
406 av_freep(&tmp_select);
407 return ret;
408 }
409
410 static void log_slave(TeeSlave *slave, void *log_ctx, int log_level)
411 {
412 av_log(log_ctx, log_level, "filename:'%s' format:%s\n",
413 slave->avf->url, slave->avf->oformat->name);
414 for (unsigned i = 0; i < slave->avf->nb_streams; i++) {
415 AVStream *st = slave->avf->streams[i];
416 AVBSFContext *bsf = slave->bsfs[i];
417 const char *bsf_name;
418
419 av_log(log_ctx, log_level, " stream:%d codec:%s type:%s",
420 i, avcodec_get_name(st->codecpar->codec_id),
421 av_get_media_type_string(st->codecpar->codec_type));
422
423 bsf_name = bsf->filter->priv_class ?
424 bsf->filter->priv_class->item_name(bsf) : bsf->filter->name;
425 av_log(log_ctx, log_level, " bsfs: %s\n", bsf_name);
426 }
427 }
428
429 static int tee_process_slave_failure(AVFormatContext *avf, unsigned slave_idx, int err_n)
430 {
431 TeeContext *tee = avf->priv_data;
432 TeeSlave *tee_slave = &tee->slaves[slave_idx];
433
434 tee->nb_alive--;
435
436 close_slave(tee_slave);
437
438 if (!tee->nb_alive) {
439 av_log(avf, AV_LOG_ERROR, "All tee outputs failed.\n");
440 return err_n;
441 } else if (tee_slave->on_fail == ON_SLAVE_FAILURE_ABORT) {
442 av_log(avf, AV_LOG_ERROR, "Slave muxer #%u failed, aborting.\n", slave_idx);
443 return err_n;
444 } else {
445 av_log(avf, AV_LOG_ERROR, "Slave muxer #%u failed: %s, continuing with %u/%u slaves.\n",
446 slave_idx, av_err2str(err_n), tee->nb_alive, tee->nb_slaves);
447 return 0;
448 }
449 }
450
451 static int tee_write_header(AVFormatContext *avf)
452 {
453 TeeContext *tee = avf->priv_data;
454 unsigned nb_slaves = 0;
455 const char *filename = avf->url;
456 char **slaves = NULL;
457 int ret;
458
459 while (*filename) {
460 char *slave = av_get_token(&filename, slave_delim);
461 if (!slave) {
462 ret = AVERROR(ENOMEM);
463 goto fail;
464 }
465 ret = av_dynarray_add_nofree(&slaves, &nb_slaves, slave);
466 if (ret < 0) {
467 av_free(slave);
468 goto fail;
469 }
470 if (strspn(filename, slave_delim))
471 filename++;
472 }
473
474 if (!FF_ALLOCZ_TYPED_ARRAY(tee->slaves, nb_slaves)) {
475 ret = AVERROR(ENOMEM);
476 goto fail;
477 }
478 tee->nb_slaves = tee->nb_alive = nb_slaves;
479
480 for (unsigned i = 0; i < nb_slaves; i++) {
481
482 tee->slaves[i].use_fifo = tee->use_fifo;
483 ret = av_dict_copy(&tee->slaves[i].fifo_options, tee->fifo_options, 0);
484 if (ret < 0)
485 goto fail;
486
487 if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0) {
488 ret = tee_process_slave_failure(avf, i, ret);
489 if (ret < 0)
490 goto fail;
491 } else {
492 log_slave(&tee->slaves[i], avf, AV_LOG_VERBOSE);
493 }
494 av_freep(&slaves[i]);
495 }
496
497 for (unsigned i = 0; i < avf->nb_streams; i++) {
498 int mapped = 0;
499 for (unsigned j = 0; j < tee->nb_slaves; j++)
500 if (tee->slaves[j].avf)
501 mapped += tee->slaves[j].stream_map[i] >= 0;
502 if (!mapped)
503 av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped "
504 "to any slave.\n", i);
505 }
506 av_free(slaves);
507 return 0;
508
509 fail:
510 for (unsigned i = 0; i < nb_slaves; i++)
511 av_freep(&slaves[i]);
512 close_slaves(avf);
513 av_free(slaves);
514 return ret;
515 }
516
517 static int tee_write_trailer(AVFormatContext *avf)
518 {
519 TeeContext *tee = avf->priv_data;
520 int ret_all = 0, ret;
521
522 for (unsigned i = 0; i < tee->nb_slaves; i++) {
523 if ((ret = close_slave(&tee->slaves[i])) < 0) {
524 ret = tee_process_slave_failure(avf, i, ret);
525 if (!ret_all && ret < 0)
526 ret_all = ret;
527 }
528 }
529 av_freep(&tee->slaves);
530 return ret_all;
531 }
532
533 static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt)
534 {
535 TeeContext *tee = avf->priv_data;
536 AVPacket *const pkt2 = ffformatcontext(avf)->pkt;
537 int ret_all = 0, ret;
538 unsigned s;
539 int s2;
540
541 for (unsigned i = 0; i < tee->nb_slaves; i++) {
542 AVFormatContext *avf2 = tee->slaves[i].avf;
543 AVBSFContext *bsfs;
544
545 if (!avf2)
546 continue;
547
548 /* Flush slave if pkt is NULL*/
549 if (!pkt) {
550 ret = av_interleaved_write_frame(avf2, NULL);
551 if (ret < 0) {
552 ret = tee_process_slave_failure(avf, i, ret);
553 if (!ret_all && ret < 0)
554 ret_all = ret;
555 }
556 continue;
557 }
558
559 s = pkt->stream_index;
560 s2 = tee->slaves[i].stream_map[s];
561 if (s2 < 0)
562 continue;
563
564 if ((ret = av_packet_ref(pkt2, pkt)) < 0) {
565 if (!ret_all)
566 ret_all = ret;
567 continue;
568 }
569 bsfs = tee->slaves[i].bsfs[s2];
570 pkt2->stream_index = s2;
571
572 ret = av_bsf_send_packet(bsfs, pkt2);
573 if (ret < 0) {
574 av_packet_unref(pkt2);
575 av_log(avf, AV_LOG_ERROR, "Error while sending packet to bitstream filter: %s\n",
576 av_err2str(ret));
577 ret = tee_process_slave_failure(avf, i, ret);
578 if (!ret_all && ret < 0)
579 ret_all = ret;
580 }
581
582 while(1) {
583 ret = av_bsf_receive_packet(bsfs, pkt2);
584 if (ret == AVERROR(EAGAIN)) {
585 ret = 0;
586 break;
587 } else if (ret < 0) {
588 break;
589 }
590
591 av_packet_rescale_ts(pkt2, bsfs->time_base_out,
592 avf2->streams[s2]->time_base);
593 ret = av_interleaved_write_frame(avf2, pkt2);
594 if (ret < 0)
595 break;
596 };
597
598 if (ret < 0) {
599 ret = tee_process_slave_failure(avf, i, ret);
600 if (!ret_all && ret < 0)
601 ret_all = ret;
602 }
603 }
604 return ret_all;
605 }
606
607 const FFOutputFormat ff_tee_muxer = {
608 .p.name = "tee",
609 .p.long_name = NULL_IF_CONFIG_SMALL("Multiple muxer tee"),
610 .priv_data_size = sizeof(TeeContext),
611 .write_header = tee_write_header,
612 .write_trailer = tee_write_trailer,
613 .write_packet = tee_write_packet,
614 .p.priv_class = &tee_muxer_class,
615 .p.flags = AVFMT_NOFILE | AVFMT_TS_NEGATIVE,
616 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
617 };