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