]> git.sesse.net Git - ffmpeg/blob - libavformat/tee.c
Merge commit '65dc7ca4c8e7e56362626a5d31e563e80108f104'
[ffmpeg] / 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/opt.h"
26 #include "internal.h"
27 #include "avformat.h"
28 #include "avio_internal.h"
29
30 #define MAX_SLAVES 16
31
32 typedef enum {
33     ON_SLAVE_FAILURE_ABORT  = 1,
34     ON_SLAVE_FAILURE_IGNORE = 2
35 } SlaveFailurePolicy;
36
37 #define DEFAULT_SLAVE_FAILURE_POLICY ON_SLAVE_FAILURE_ABORT
38
39 typedef struct {
40     AVFormatContext *avf;
41     AVBitStreamFilterContext **bsfs; ///< bitstream filters per stream
42
43     SlaveFailurePolicy on_fail;
44
45     /** map from input to output streams indexes,
46      * disabled output streams are set to -1 */
47     int *stream_map;
48     int header_written;
49 } TeeSlave;
50
51 typedef struct TeeContext {
52     const AVClass *class;
53     unsigned nb_slaves;
54     unsigned nb_alive;
55     TeeSlave slaves[MAX_SLAVES];
56 } TeeContext;
57
58 static const char *const slave_delim     = "|";
59 static const char *const slave_opt_open  = "[";
60 static const char *const slave_opt_close = "]";
61 static const char *const slave_opt_delim = ":]"; /* must have the close too */
62 static const char *const slave_bsfs_spec_sep = "/";
63 static const char *const slave_select_sep = ",";
64
65 static const AVClass tee_muxer_class = {
66     .class_name = "Tee muxer",
67     .item_name  = av_default_item_name,
68     .version    = LIBAVUTIL_VERSION_INT,
69 };
70
71 static int parse_slave_options(void *log, char *slave,
72                                AVDictionary **options, char **filename)
73 {
74     const char *p;
75     char *key, *val;
76     int ret;
77
78     if (!strspn(slave, slave_opt_open)) {
79         *filename = slave;
80         return 0;
81     }
82     p = slave + 1;
83     if (strspn(p, slave_opt_close)) {
84         *filename = (char *)p + 1;
85         return 0;
86     }
87     while (1) {
88         ret = av_opt_get_key_value(&p, "=", slave_opt_delim, 0, &key, &val);
89         if (ret < 0) {
90             av_log(log, AV_LOG_ERROR, "No option found near \"%s\"\n", p);
91             goto fail;
92         }
93         ret = av_dict_set(options, key, val,
94                           AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
95         if (ret < 0)
96             goto fail;
97         if (strspn(p, slave_opt_close))
98             break;
99         p++;
100     }
101     *filename = (char *)p + 1;
102     return 0;
103
104 fail:
105     av_dict_free(options);
106     return ret;
107 }
108
109 /**
110  * Parse list of bitstream filters and add them to the list of filters
111  * pointed to by bsfs.
112  *
113  * The list must be specified in the form:
114  * BSFS ::= BSF[,BSFS]
115  */
116 static int parse_bsfs(void *log_ctx, const char *bsfs_spec,
117                       AVBitStreamFilterContext **bsfs)
118 {
119     char *bsf_name, *buf, *dup, *saveptr;
120     int ret = 0;
121
122     if (!(dup = buf = av_strdup(bsfs_spec)))
123         return AVERROR(ENOMEM);
124
125     while (bsf_name = av_strtok(buf, ",", &saveptr)) {
126         AVBitStreamFilterContext *bsf = av_bitstream_filter_init(bsf_name);
127
128         if (!bsf) {
129             av_log(log_ctx, AV_LOG_ERROR,
130                    "Cannot initialize bitstream filter with name '%s', "
131                    "unknown filter or internal error happened\n",
132                    bsf_name);
133             ret = AVERROR_UNKNOWN;
134             goto end;
135         }
136
137         /* append bsf context to the list of bsf contexts */
138         *bsfs = bsf;
139         bsfs = &bsf->next;
140
141         buf = NULL;
142     }
143
144 end:
145     av_free(dup);
146     return ret;
147 }
148
149 static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *tee_slave)
150 {
151     if (!opt) {
152         tee_slave->on_fail = DEFAULT_SLAVE_FAILURE_POLICY;
153         return 0;
154     } else if (!av_strcasecmp("abort", opt)) {
155         tee_slave->on_fail = ON_SLAVE_FAILURE_ABORT;
156         return 0;
157     } else if (!av_strcasecmp("ignore", opt)) {
158         tee_slave->on_fail = ON_SLAVE_FAILURE_IGNORE;
159         return 0;
160     }
161     /* Set failure behaviour to abort, so invalid option error will not be ignored */
162     tee_slave->on_fail = ON_SLAVE_FAILURE_ABORT;
163     return AVERROR(EINVAL);
164 }
165
166 static int close_slave(TeeSlave *tee_slave)
167 {
168     AVFormatContext *avf;
169     unsigned i;
170     int ret = 0;
171
172     avf = tee_slave->avf;
173     if (!avf)
174         return 0;
175
176     if (tee_slave->header_written)
177         ret = av_write_trailer(avf);
178
179     if (tee_slave->bsfs) {
180         for (i = 0; i < avf->nb_streams; ++i) {
181             AVBitStreamFilterContext *bsf_next, *bsf = tee_slave->bsfs[i];
182             while (bsf) {
183                 bsf_next = bsf->next;
184                 av_bitstream_filter_close(bsf);
185                 bsf = bsf_next;
186             }
187         }
188     }
189     av_freep(&tee_slave->stream_map);
190     av_freep(&tee_slave->bsfs);
191
192     ff_format_io_close(avf, &avf->pb);
193     avformat_free_context(avf);
194     tee_slave->avf = NULL;
195     return ret;
196 }
197
198 static void close_slaves(AVFormatContext *avf)
199 {
200     TeeContext *tee = avf->priv_data;
201     unsigned i;
202
203     for (i = 0; i < tee->nb_slaves; i++) {
204         close_slave(&tee->slaves[i]);
205     }
206 }
207
208 static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
209 {
210     int i, ret;
211     AVDictionary *options = NULL;
212     AVDictionaryEntry *entry;
213     char *filename;
214     char *format = NULL, *select = NULL, *on_fail = NULL;
215     AVFormatContext *avf2 = NULL;
216     AVStream *st, *st2;
217     int stream_count;
218     int fullret;
219     char *subselect = NULL, *next_subselect = NULL, *first_subselect = NULL, *tmp_select = NULL;
220
221     if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0)
222         return ret;
223
224 #define STEAL_OPTION(option, field) do {                                \
225         if ((entry = av_dict_get(options, option, NULL, 0))) {          \
226             field = entry->value;                                       \
227             entry->value = NULL; /* prevent it from being freed */      \
228             av_dict_set(&options, option, NULL, 0);                     \
229         }                                                               \
230     } while (0)
231
232     STEAL_OPTION("f", format);
233     STEAL_OPTION("select", select);
234     STEAL_OPTION("onfail", on_fail);
235
236     ret = parse_slave_failure_policy_option(on_fail, tee_slave);
237     if (ret < 0) {
238         av_log(avf, AV_LOG_ERROR,
239                "Invalid onfail option value, valid options are 'abort' and 'ignore'\n");
240         goto end;
241     }
242
243     ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
244     if (ret < 0)
245         goto end;
246     tee_slave->avf = avf2;
247     av_dict_copy(&avf2->metadata, avf->metadata, 0);
248     avf2->opaque   = avf->opaque;
249     avf2->io_open  = avf->io_open;
250     avf2->io_close = avf->io_close;
251
252     tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map));
253     if (!tee_slave->stream_map) {
254         ret = AVERROR(ENOMEM);
255         goto end;
256     }
257
258     stream_count = 0;
259     for (i = 0; i < avf->nb_streams; i++) {
260         st = avf->streams[i];
261         if (select) {
262             tmp_select = av_strdup(select);  // av_strtok is destructive so we regenerate it in each loop
263             if (!tmp_select) {
264                 ret = AVERROR(ENOMEM);
265                 goto end;
266             }
267             fullret = 0;
268             first_subselect = tmp_select;
269             next_subselect = NULL;
270             while (subselect = av_strtok(first_subselect, slave_select_sep, &next_subselect)) {
271                 first_subselect = NULL;
272
273                 ret = avformat_match_stream_specifier(avf, avf->streams[i], subselect);
274                 if (ret < 0) {
275                     av_log(avf, AV_LOG_ERROR,
276                            "Invalid stream specifier '%s' for output '%s'\n",
277                            subselect, slave);
278                     goto end;
279                 }
280                 if (ret != 0) {
281                     fullret = 1; // match
282                     break;
283                 }
284             }
285             av_freep(&tmp_select);
286
287             if (fullret == 0) { /* no match */
288                 tee_slave->stream_map[i] = -1;
289                 continue;
290             }
291         }
292         tee_slave->stream_map[i] = stream_count++;
293
294         if (!(st2 = avformat_new_stream(avf2, NULL))) {
295             ret = AVERROR(ENOMEM);
296             goto end;
297         }
298         st2->id = st->id;
299         st2->r_frame_rate        = st->r_frame_rate;
300         st2->time_base           = st->time_base;
301         st2->start_time          = st->start_time;
302         st2->duration            = st->duration;
303         st2->nb_frames           = st->nb_frames;
304         st2->disposition         = st->disposition;
305         st2->sample_aspect_ratio = st->sample_aspect_ratio;
306         st2->avg_frame_rate      = st->avg_frame_rate;
307         av_dict_copy(&st2->metadata, st->metadata, 0);
308         if ((ret = avcodec_parameters_copy(st2->codecpar, st->codecpar)) < 0)
309             goto end;
310     }
311
312     if (!(avf2->oformat->flags & AVFMT_NOFILE)) {
313         if ((ret = avf2->io_open(avf2, &avf2->pb, filename, AVIO_FLAG_WRITE, NULL)) < 0) {
314             av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n",
315                    slave, av_err2str(ret));
316             goto end;
317         }
318     }
319
320     if ((ret = avformat_write_header(avf2, &options)) < 0) {
321         av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n",
322                slave, av_err2str(ret));
323         goto end;
324     }
325     tee_slave->header_written = 1;
326
327     tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(*tee_slave->bsfs));
328     if (!tee_slave->bsfs) {
329         ret = AVERROR(ENOMEM);
330         goto end;
331     }
332
333     entry = NULL;
334     while (entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX)) {
335         const char *spec = entry->key + strlen("bsfs");
336         if (*spec) {
337             if (strspn(spec, slave_bsfs_spec_sep) != 1) {
338                 av_log(avf, AV_LOG_ERROR,
339                        "Specifier separator in '%s' is '%c', but only characters '%s' "
340                        "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep);
341                 ret = AVERROR(EINVAL);
342                 goto end;
343             }
344             spec++; /* consume separator */
345         }
346
347         for (i = 0; i < avf2->nb_streams; i++) {
348             ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec);
349             if (ret < 0) {
350                 av_log(avf, AV_LOG_ERROR,
351                        "Invalid stream specifier '%s' in bsfs option '%s' for slave "
352                        "output '%s'\n", spec, entry->key, filename);
353                 goto end;
354             }
355
356             if (ret > 0) {
357                 av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave "
358                        "output '%s'\n", spec, entry->value, i, filename);
359                 if (tee_slave->bsfs[i]) {
360                     av_log(avf, AV_LOG_WARNING,
361                            "Duplicate bsfs specification associated to stream %d of slave "
362                            "output '%s', filters will be ignored\n", i, filename);
363                     continue;
364                 }
365                 ret = parse_bsfs(avf, entry->value, &tee_slave->bsfs[i]);
366                 if (ret < 0) {
367                     av_log(avf, AV_LOG_ERROR,
368                            "Error parsing bitstream filter sequence '%s' associated to "
369                            "stream %d of slave output '%s'\n", entry->value, i, filename);
370                     goto end;
371                 }
372             }
373         }
374
375         av_dict_set(&options, entry->key, NULL, 0);
376     }
377
378     if (options) {
379         entry = NULL;
380         while ((entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX)))
381             av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
382         ret = AVERROR_OPTION_NOT_FOUND;
383         goto end;
384     }
385
386 end:
387     av_free(format);
388     av_free(select);
389     av_free(on_fail);
390     av_dict_free(&options);
391     av_freep(&tmp_select);
392     return ret;
393 }
394
395 static void log_slave(TeeSlave *slave, void *log_ctx, int log_level)
396 {
397     int i;
398     av_log(log_ctx, log_level, "filename:'%s' format:%s\n",
399            slave->avf->filename, slave->avf->oformat->name);
400     for (i = 0; i < slave->avf->nb_streams; i++) {
401         AVStream *st = slave->avf->streams[i];
402         AVBitStreamFilterContext *bsf = slave->bsfs[i];
403
404         av_log(log_ctx, log_level, "    stream:%d codec:%s type:%s",
405                i, avcodec_get_name(st->codecpar->codec_id),
406                av_get_media_type_string(st->codecpar->codec_type));
407         if (bsf) {
408             av_log(log_ctx, log_level, " bsfs:");
409             while (bsf) {
410                 av_log(log_ctx, log_level, "%s%s",
411                        bsf->filter->name, bsf->next ? "," : "");
412                 bsf = bsf->next;
413             }
414         }
415         av_log(log_ctx, log_level, "\n");
416     }
417 }
418
419 static int tee_process_slave_failure(AVFormatContext *avf, unsigned slave_idx, int err_n)
420 {
421     TeeContext *tee = avf->priv_data;
422     TeeSlave *tee_slave = &tee->slaves[slave_idx];
423
424     tee->nb_alive--;
425
426     close_slave(tee_slave);
427
428     if (!tee->nb_alive) {
429         av_log(avf, AV_LOG_ERROR, "All tee outputs failed.\n");
430         return err_n;
431     } else if (tee_slave->on_fail == ON_SLAVE_FAILURE_ABORT) {
432         av_log(avf, AV_LOG_ERROR, "Slave muxer #%u failed, aborting.\n", slave_idx);
433         return err_n;
434     } else {
435         av_log(avf, AV_LOG_ERROR, "Slave muxer #%u failed: %s, continuing with %u/%u slaves.\n",
436                slave_idx, av_err2str(err_n), tee->nb_alive, tee->nb_slaves);
437         return 0;
438     }
439 }
440
441 static int tee_write_header(AVFormatContext *avf)
442 {
443     TeeContext *tee = avf->priv_data;
444     unsigned nb_slaves = 0, i;
445     const char *filename = avf->filename;
446     char *slaves[MAX_SLAVES];
447     int ret;
448
449     while (*filename) {
450         if (nb_slaves == MAX_SLAVES) {
451             av_log(avf, AV_LOG_ERROR, "Maximum %d slave muxers reached.\n",
452                    MAX_SLAVES);
453             ret = AVERROR_PATCHWELCOME;
454             goto fail;
455         }
456         if (!(slaves[nb_slaves++] = av_get_token(&filename, slave_delim))) {
457             ret = AVERROR(ENOMEM);
458             goto fail;
459         }
460         if (strspn(filename, slave_delim))
461             filename++;
462     }
463
464     tee->nb_slaves = tee->nb_alive = nb_slaves;
465
466     for (i = 0; i < nb_slaves; i++) {
467         if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0) {
468             ret = tee_process_slave_failure(avf, i, ret);
469             if (ret < 0)
470                 goto fail;
471         } else {
472             log_slave(&tee->slaves[i], avf, AV_LOG_VERBOSE);
473         }
474         av_freep(&slaves[i]);
475     }
476
477     for (i = 0; i < avf->nb_streams; i++) {
478         int j, mapped = 0;
479         for (j = 0; j < tee->nb_slaves; j++)
480             if (tee->slaves[j].avf)
481                 mapped += tee->slaves[j].stream_map[i] >= 0;
482         if (!mapped)
483             av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped "
484                    "to any slave.\n", i);
485     }
486     return 0;
487
488 fail:
489     for (i = 0; i < nb_slaves; i++)
490         av_freep(&slaves[i]);
491     close_slaves(avf);
492     return ret;
493 }
494
495 static int tee_write_trailer(AVFormatContext *avf)
496 {
497     TeeContext *tee = avf->priv_data;
498     int ret_all = 0, ret;
499     unsigned i;
500
501     for (i = 0; i < tee->nb_slaves; i++) {
502         if ((ret = close_slave(&tee->slaves[i])) < 0) {
503             ret = tee_process_slave_failure(avf, i, ret);
504             if (!ret_all && ret < 0)
505                 ret_all = ret;
506         }
507     }
508     return ret_all;
509 }
510
511 static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt)
512 {
513     TeeContext *tee = avf->priv_data;
514     AVFormatContext *avf2;
515     AVPacket pkt2;
516     int ret_all = 0, ret;
517     unsigned i, s;
518     int s2;
519     AVRational tb, tb2;
520
521     for (i = 0; i < tee->nb_slaves; i++) {
522         if (!(avf2 = tee->slaves[i].avf))
523             continue;
524
525         s = pkt->stream_index;
526         s2 = tee->slaves[i].stream_map[s];
527         if (s2 < 0)
528             continue;
529
530         memset(&pkt2, 0, sizeof(AVPacket));
531         if ((ret = av_packet_ref(&pkt2, pkt)) < 0)
532             if (!ret_all) {
533                 ret_all = ret;
534                 continue;
535             }
536         tb  = avf ->streams[s ]->time_base;
537         tb2 = avf2->streams[s2]->time_base;
538         pkt2.pts      = av_rescale_q(pkt->pts,      tb, tb2);
539         pkt2.dts      = av_rescale_q(pkt->dts,      tb, tb2);
540         pkt2.duration = av_rescale_q(pkt->duration, tb, tb2);
541         pkt2.stream_index = s2;
542
543         if ((ret = av_apply_bitstream_filters(avf2->streams[s2]->codec, &pkt2,
544                                               tee->slaves[i].bsfs[s2])) < 0 ||
545             (ret = av_interleaved_write_frame(avf2, &pkt2)) < 0) {
546             ret = tee_process_slave_failure(avf, i, ret);
547             if (!ret_all && ret < 0)
548                 ret_all = ret;
549         }
550     }
551     return ret_all;
552 }
553
554 AVOutputFormat ff_tee_muxer = {
555     .name              = "tee",
556     .long_name         = NULL_IF_CONFIG_SMALL("Multiple muxer tee"),
557     .priv_data_size    = sizeof(TeeContext),
558     .write_header      = tee_write_header,
559     .write_trailer     = tee_write_trailer,
560     .write_packet      = tee_write_packet,
561     .priv_class        = &tee_muxer_class,
562     .flags             = AVFMT_NOFILE,
563 };