3 * Copyright (c) 2012 Nicolas George
5 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/avutil.h"
24 #include "libavutil/avstring.h"
25 #include "libavutil/opt.h"
32 AVBitStreamFilterContext
**bsfs
; ///< bitstream filters per stream
34 /** map from input to output streams indexes,
35 * disabled output streams are set to -1 */
39 typedef struct TeeContext
{
42 TeeSlave slaves
[MAX_SLAVES
];
45 static const char *const slave_delim
= "|";
46 static const char *const slave_opt_open
= "[";
47 static const char *const slave_opt_close
= "]";
48 static const char *const slave_opt_delim
= ":]"; /* must have the close too */
49 static const char *const slave_bsfs_spec_sep
= "/";
51 static const AVClass tee_muxer_class
= {
52 .class_name
= "Tee muxer",
53 .item_name
= av_default_item_name
,
54 .version
= LIBAVUTIL_VERSION_INT
,
57 static int parse_slave_options(void *log
, char *slave
,
58 AVDictionary
**options
, char **filename
)
64 if (!strspn(slave
, slave_opt_open
)) {
69 if (strspn(p
, slave_opt_close
)) {
70 *filename
= (char *)p
+ 1;
74 ret
= av_opt_get_key_value(&p
, "=", slave_opt_delim
, 0, &key
, &val
);
76 av_log(log
, AV_LOG_ERROR
, "No option found near \"%s\"\n", p
);
79 ret
= av_dict_set(options
, key
, val
,
80 AV_DICT_DONT_STRDUP_KEY
| AV_DICT_DONT_STRDUP_VAL
);
83 if (strspn(p
, slave_opt_close
))
87 *filename
= (char *)p
+ 1;
91 av_dict_free(options
);
96 * Parse list of bitstream filters and add them to the list of filters
99 * The list must be specified in the form:
100 * BSFS ::= BSF[,BSFS]
102 static int parse_bsfs(void *log_ctx
, const char *bsfs_spec
,
103 AVBitStreamFilterContext
**bsfs
)
105 char *bsf_name
, *buf
, *dup
, *saveptr
;
108 if (!(dup
= buf
= av_strdup(bsfs_spec
)))
109 return AVERROR(ENOMEM
);
111 while (bsf_name
= av_strtok(buf
, ",", &saveptr
)) {
112 AVBitStreamFilterContext
*bsf
= av_bitstream_filter_init(bsf_name
);
115 av_log(log_ctx
, AV_LOG_ERROR
,
116 "Cannot initialize bitstream filter with name '%s', "
117 "unknown filter or internal error happened\n",
119 ret
= AVERROR_UNKNOWN
;
123 /* append bsf context to the list of bsf contexts */
135 static int open_slave(AVFormatContext
*avf
, char *slave
, TeeSlave
*tee_slave
)
138 AVDictionary
*options
= NULL
;
139 AVDictionaryEntry
*entry
;
141 char *format
= NULL
, *select
= NULL
;
142 AVFormatContext
*avf2
= NULL
;
146 if ((ret
= parse_slave_options(avf
, slave
, &options
, &filename
)) < 0)
149 #define STEAL_OPTION(option, field) do { \
150 if ((entry = av_dict_get(options, option, NULL, 0))) { \
151 field = entry->value; \
152 entry->value = NULL; /* prevent it from being freed */ \
153 av_dict_set(&options, option, NULL, 0); \
157 STEAL_OPTION("f", format
);
158 STEAL_OPTION("select", select
);
160 ret
= avformat_alloc_output_context2(&avf2
, NULL
, format
, filename
);
163 av_dict_copy(&avf2
->metadata
, avf
->metadata
, 0);
165 tee_slave
->stream_map
= av_calloc(avf
->nb_streams
, sizeof(*tee_slave
->stream_map
));
166 if (!tee_slave
->stream_map
) {
167 ret
= AVERROR(ENOMEM
);
172 for (i
= 0; i
< avf
->nb_streams
; i
++) {
173 st
= avf
->streams
[i
];
175 ret
= avformat_match_stream_specifier(avf
, avf
->streams
[i
], select
);
177 av_log(avf
, AV_LOG_ERROR
,
178 "Invalid stream specifier '%s' for output '%s'\n",
183 if (ret
== 0) { /* no match */
184 tee_slave
->stream_map
[i
] = -1;
188 tee_slave
->stream_map
[i
] = stream_count
++;
190 if (!(st2
= avformat_new_stream(avf2
, NULL
))) {
191 ret
= AVERROR(ENOMEM
);
195 st2
->r_frame_rate
= st
->r_frame_rate
;
196 st2
->time_base
= st
->time_base
;
197 st2
->start_time
= st
->start_time
;
198 st2
->duration
= st
->duration
;
199 st2
->nb_frames
= st
->nb_frames
;
200 st2
->disposition
= st
->disposition
;
201 st2
->sample_aspect_ratio
= st
->sample_aspect_ratio
;
202 st2
->avg_frame_rate
= st
->avg_frame_rate
;
203 av_dict_copy(&st2
->metadata
, st
->metadata
, 0);
204 if ((ret
= avcodec_copy_context(st2
->codec
, st
->codec
)) < 0)
208 if (!(avf2
->oformat
->flags
& AVFMT_NOFILE
)) {
209 if ((ret
= avio_open(&avf2
->pb
, filename
, AVIO_FLAG_WRITE
)) < 0) {
210 av_log(avf
, AV_LOG_ERROR
, "Slave '%s': error opening: %s\n",
211 slave
, av_err2str(ret
));
216 if ((ret
= avformat_write_header(avf2
, &options
)) < 0) {
217 av_log(avf
, AV_LOG_ERROR
, "Slave '%s': error writing header: %s\n",
218 slave
, av_err2str(ret
));
222 tee_slave
->avf
= avf2
;
223 tee_slave
->bsfs
= av_calloc(avf2
->nb_streams
, sizeof(TeeSlave
));
224 if (!tee_slave
->bsfs
) {
225 ret
= AVERROR(ENOMEM
);
230 while (entry
= av_dict_get(options
, "bsfs", NULL
, AV_DICT_IGNORE_SUFFIX
)) {
231 const char *spec
= entry
->key
+ strlen("bsfs");
233 if (strspn(spec
, slave_bsfs_spec_sep
) != 1) {
234 av_log(avf
, AV_LOG_ERROR
,
235 "Specifier separator in '%s' is '%c', but only characters '%s' "
236 "are allowed\n", entry
->key
, *spec
, slave_bsfs_spec_sep
);
237 return AVERROR(EINVAL
);
239 spec
++; /* consume separator */
242 for (i
= 0; i
< avf2
->nb_streams
; i
++) {
243 ret
= avformat_match_stream_specifier(avf2
, avf2
->streams
[i
], spec
);
245 av_log(avf
, AV_LOG_ERROR
,
246 "Invalid stream specifier '%s' in bsfs option '%s' for slave "
247 "output '%s'\n", spec
, entry
->key
, filename
);
252 av_log(avf
, AV_LOG_DEBUG
, "spec:%s bsfs:%s matches stream %d of slave "
253 "output '%s'\n", spec
, entry
->value
, i
, filename
);
254 if (tee_slave
->bsfs
[i
]) {
255 av_log(avf
, AV_LOG_WARNING
,
256 "Duplicate bsfs specification associated to stream %d of slave "
257 "output '%s', filters will be ignored\n", i
, filename
);
260 ret
= parse_bsfs(avf
, entry
->value
, &tee_slave
->bsfs
[i
]);
262 av_log(avf
, AV_LOG_ERROR
,
263 "Error parsing bitstream filter sequence '%s' associated to "
264 "stream %d of slave output '%s'\n", entry
->value
, i
, filename
);
270 av_dict_set(&options
, entry
->key
, NULL
, 0);
275 while ((entry
= av_dict_get(options
, "", entry
, AV_DICT_IGNORE_SUFFIX
)))
276 av_log(avf2
, AV_LOG_ERROR
, "Unknown option '%s'\n", entry
->key
);
277 ret
= AVERROR_OPTION_NOT_FOUND
;
284 av_dict_free(&options
);
288 static void close_slaves(AVFormatContext
*avf
)
290 TeeContext
*tee
= avf
->priv_data
;
291 AVFormatContext
*avf2
;
294 for (i
= 0; i
< tee
->nb_slaves
; i
++) {
295 avf2
= tee
->slaves
[i
].avf
;
297 for (j
= 0; j
< avf2
->nb_streams
; j
++) {
298 AVBitStreamFilterContext
*bsf_next
, *bsf
= tee
->slaves
[i
].bsfs
[j
];
300 bsf_next
= bsf
->next
;
301 av_bitstream_filter_close(bsf
);
305 av_freep(&tee
->slaves
[i
].stream_map
);
306 av_freep(&tee
->slaves
[i
].bsfs
);
308 avio_close(avf2
->pb
);
310 avformat_free_context(avf2
);
311 tee
->slaves
[i
].avf
= NULL
;
315 static void log_slave(TeeSlave
*slave
, void *log_ctx
, int log_level
)
318 av_log(log_ctx
, log_level
, "filename:'%s' format:%s\n",
319 slave
->avf
->filename
, slave
->avf
->oformat
->name
);
320 for (i
= 0; i
< slave
->avf
->nb_streams
; i
++) {
321 AVStream
*st
= slave
->avf
->streams
[i
];
322 AVBitStreamFilterContext
*bsf
= slave
->bsfs
[i
];
324 av_log(log_ctx
, log_level
, " stream:%d codec:%s type:%s",
325 i
, avcodec_get_name(st
->codec
->codec_id
),
326 av_get_media_type_string(st
->codec
->codec_type
));
328 av_log(log_ctx
, log_level
, " bsfs:");
330 av_log(log_ctx
, log_level
, "%s%s",
331 bsf
->filter
->name
, bsf
->next
? "," : "");
335 av_log(log_ctx
, log_level
, "\n");
339 static int tee_write_header(AVFormatContext
*avf
)
341 TeeContext
*tee
= avf
->priv_data
;
342 unsigned nb_slaves
= 0, i
;
343 const char *filename
= avf
->filename
;
344 char *slaves
[MAX_SLAVES
];
348 if (nb_slaves
== MAX_SLAVES
) {
349 av_log(avf
, AV_LOG_ERROR
, "Maximum %d slave muxers reached.\n",
351 ret
= AVERROR_PATCHWELCOME
;
354 if (!(slaves
[nb_slaves
++] = av_get_token(&filename
, slave_delim
))) {
355 ret
= AVERROR(ENOMEM
);
358 if (strspn(filename
, slave_delim
))
362 for (i
= 0; i
< nb_slaves
; i
++) {
363 if ((ret
= open_slave(avf
, slaves
[i
], &tee
->slaves
[i
])) < 0)
365 log_slave(&tee
->slaves
[i
], avf
, AV_LOG_VERBOSE
);
366 av_freep(&slaves
[i
]);
369 tee
->nb_slaves
= nb_slaves
;
371 for (i
= 0; i
< avf
->nb_streams
; i
++) {
373 for (j
= 0; j
< tee
->nb_slaves
; j
++)
374 mapped
+= tee
->slaves
[j
].stream_map
[i
] >= 0;
376 av_log(avf
, AV_LOG_WARNING
, "Input stream #%d is not mapped "
377 "to any slave.\n", i
);
382 for (i
= 0; i
< nb_slaves
; i
++)
383 av_freep(&slaves
[i
]);
388 static int filter_packet(void *log_ctx
, AVPacket
*pkt
,
389 AVFormatContext
*fmt_ctx
, AVBitStreamFilterContext
*bsf_ctx
)
391 AVCodecContext
*enc_ctx
= fmt_ctx
->streams
[pkt
->stream_index
]->codec
;
395 AVPacket new_pkt
= *pkt
;
396 ret
= av_bitstream_filter_filter(bsf_ctx
, enc_ctx
, NULL
,
397 &new_pkt
.data
, &new_pkt
.size
,
398 pkt
->data
, pkt
->size
,
399 pkt
->flags
& AV_PKT_FLAG_KEY
);
400 if (ret
== 0 && new_pkt
.data
!= pkt
->data
&& new_pkt
.destruct
) {
401 if ((ret
= av_copy_packet(&new_pkt
, pkt
)) < 0)
408 new_pkt
.buf
= av_buffer_create(new_pkt
.data
, new_pkt
.size
,
409 av_buffer_default_free
, NULL
, 0);
414 av_log(log_ctx
, AV_LOG_ERROR
,
415 "Failed to filter bitstream with filter %s for stream %d in file '%s' with codec %s\n",
416 bsf_ctx
->filter
->name
, pkt
->stream_index
, fmt_ctx
->filename
,
417 avcodec_get_name(enc_ctx
->codec_id
));
421 bsf_ctx
= bsf_ctx
->next
;
427 static int tee_write_trailer(AVFormatContext
*avf
)
429 TeeContext
*tee
= avf
->priv_data
;
430 AVFormatContext
*avf2
;
431 int ret_all
= 0, ret
;
434 for (i
= 0; i
< tee
->nb_slaves
; i
++) {
435 avf2
= tee
->slaves
[i
].avf
;
436 if ((ret
= av_write_trailer(avf2
)) < 0)
439 if (!(avf2
->oformat
->flags
& AVFMT_NOFILE
)) {
440 if ((ret
= avio_close(avf2
->pb
)) < 0)
450 static int tee_write_packet(AVFormatContext
*avf
, AVPacket
*pkt
)
452 TeeContext
*tee
= avf
->priv_data
;
453 AVFormatContext
*avf2
;
455 int ret_all
= 0, ret
;
460 for (i
= 0; i
< tee
->nb_slaves
; i
++) {
461 avf2
= tee
->slaves
[i
].avf
;
462 s
= pkt
->stream_index
;
463 s2
= tee
->slaves
[i
].stream_map
[s
];
467 if ((ret
= av_copy_packet(&pkt2
, pkt
)) < 0 ||
468 (ret
= av_dup_packet(&pkt2
))< 0)
473 tb
= avf
->streams
[s
]->time_base
;
474 tb2
= avf2
->streams
[s2
]->time_base
;
475 pkt2
.pts
= av_rescale_q(pkt
->pts
, tb
, tb2
);
476 pkt2
.dts
= av_rescale_q(pkt
->dts
, tb
, tb2
);
477 pkt2
.duration
= av_rescale_q(pkt
->duration
, tb
, tb2
);
478 pkt2
.stream_index
= s2
;
480 filter_packet(avf2
, &pkt2
, avf2
, tee
->slaves
[i
].bsfs
[s2
]);
481 if ((ret
= av_interleaved_write_frame(avf2
, &pkt2
)) < 0)
488 AVOutputFormat ff_tee_muxer
= {
490 .long_name
= NULL_IF_CONFIG_SMALL("Multiple muxer tee"),
491 .priv_data_size
= sizeof(TeeContext
),
492 .write_header
= tee_write_header
,
493 .write_trailer
= tee_write_trailer
,
494 .write_packet
= tee_write_packet
,
495 .priv_class
= &tee_muxer_class
,
496 .flags
= AVFMT_NOFILE
,