You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
lavf/tee: allow multiple stream specifiers in select.
It makes possible to put multiple stream specifier into the select option separated by comma. eg. select=\'a:0,v\' Signed-off-by: Bela Bodecs <bodecsb@vivanet.hu> Signed-off-by: Nicolas George <george@nsup.org>
This commit is contained in:
committed by
Nicolas George
parent
b3deaece87
commit
1f3a29e999
@@ -1272,7 +1272,8 @@ Several bitstream filters can be specified, separated by ",".
|
|||||||
@item select
|
@item select
|
||||||
Select the streams that should be mapped to the slave output,
|
Select the streams that should be mapped to the slave output,
|
||||||
specified by a stream specifier. If not specified, this defaults to
|
specified by a stream specifier. If not specified, this defaults to
|
||||||
all the input streams.
|
all the input streams. You may use multiple stream specifiers
|
||||||
|
separated by commas (@code{,}) e.g.: @code{a:0,v}
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
@subsection Examples
|
||||||
|
@@ -47,6 +47,7 @@ static const char *const slave_opt_open = "[";
|
|||||||
static const char *const slave_opt_close = "]";
|
static const char *const slave_opt_close = "]";
|
||||||
static const char *const slave_opt_delim = ":]"; /* must have the close too */
|
static const char *const slave_opt_delim = ":]"; /* must have the close too */
|
||||||
static const char *const slave_bsfs_spec_sep = "/";
|
static const char *const slave_bsfs_spec_sep = "/";
|
||||||
|
static const char *const slave_select_sep = ",";
|
||||||
|
|
||||||
static const AVClass tee_muxer_class = {
|
static const AVClass tee_muxer_class = {
|
||||||
.class_name = "Tee muxer",
|
.class_name = "Tee muxer",
|
||||||
@@ -142,6 +143,8 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
|
|||||||
AVFormatContext *avf2 = NULL;
|
AVFormatContext *avf2 = NULL;
|
||||||
AVStream *st, *st2;
|
AVStream *st, *st2;
|
||||||
int stream_count;
|
int stream_count;
|
||||||
|
int fullret;
|
||||||
|
char *subselect = NULL, *next_subselect = NULL, *first_subselect = NULL, *tmp_select = NULL;
|
||||||
|
|
||||||
if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0)
|
if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -172,15 +175,32 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
|
|||||||
for (i = 0; i < avf->nb_streams; i++) {
|
for (i = 0; i < avf->nb_streams; i++) {
|
||||||
st = avf->streams[i];
|
st = avf->streams[i];
|
||||||
if (select) {
|
if (select) {
|
||||||
ret = avformat_match_stream_specifier(avf, avf->streams[i], select);
|
tmp_select = av_strdup(select); // av_strtok is destructive so we regenerate it in each loop
|
||||||
|
if (!tmp_select) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
fullret = 0;
|
||||||
|
first_subselect = tmp_select;
|
||||||
|
next_subselect = NULL;
|
||||||
|
while (subselect = av_strtok(first_subselect, slave_select_sep, &next_subselect)) {
|
||||||
|
first_subselect = NULL;
|
||||||
|
|
||||||
|
ret = avformat_match_stream_specifier(avf, avf->streams[i], subselect);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(avf, AV_LOG_ERROR,
|
av_log(avf, AV_LOG_ERROR,
|
||||||
"Invalid stream specifier '%s' for output '%s'\n",
|
"Invalid stream specifier '%s' for output '%s'\n",
|
||||||
select, slave);
|
subselect, slave);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if (ret != 0) {
|
||||||
|
fullret = 1; // match
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
av_freep(&tmp_select);
|
||||||
|
|
||||||
if (ret == 0) { /* no match */
|
if (fullret == 0) { /* no match */
|
||||||
tee_slave->stream_map[i] = -1;
|
tee_slave->stream_map[i] = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -282,6 +302,7 @@ end:
|
|||||||
av_free(format);
|
av_free(format);
|
||||||
av_free(select);
|
av_free(select);
|
||||||
av_dict_free(&options);
|
av_dict_free(&options);
|
||||||
|
av_freep(&tmp_select);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user