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