summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2014-12-20 18:18:48 +0100
committerMarton Balint <cus@passwd.hu>2015-01-01 14:38:12 +0100
commit5e7dcb0491cc9c6d8c6f964605fadcbb10831ff9 (patch)
tree6a396de3eae1dea2dd2a6e5cda6f5357c26fde55
parent82928656b134b48599e1b7ee32fde1aaf81ea9f6 (diff)
downloadffmpeg-streaming-5e7dcb0491cc9c6d8c6f964605fadcbb10831ff9.zip
ffmpeg-streaming-5e7dcb0491cc9c6d8c6f964605fadcbb10831ff9.tar.gz
ffplay: add support for stream specifiers in -ast, -vst, -sst options
Also fix the outdated documentation of these options. Signed-off-by: Marton Balint <cus@passwd.hu>
-rw-r--r--doc/ffplay.texi29
-rw-r--r--ffplay.c35
2 files changed, 36 insertions, 28 deletions
diff --git a/doc/ffplay.texi b/doc/ffplay.texi
index 556fc39..45731a2 100644
--- a/doc/ffplay.texi
+++ b/doc/ffplay.texi
@@ -124,21 +124,20 @@ master clock is used to control audio-video synchronization. Most media
players use audio as master clock, but in some cases (streaming or high
quality broadcast) it is necessary to change that. This option is mainly
used for debugging purposes.
-@item -ast @var{audio_stream_number}
-Select the desired audio stream number, counting from 0. The number
-refers to the list of all the input audio streams. If it is greater
-than the number of audio streams minus one, then the last one is
-selected, if it is negative the audio playback is disabled.
-@item -vst @var{video_stream_number}
-Select the desired video stream number, counting from 0. The number
-refers to the list of all the input video streams. If it is greater
-than the number of video streams minus one, then the last one is
-selected, if it is negative the video playback is disabled.
-@item -sst @var{subtitle_stream_number}
-Select the desired subtitle stream number, counting from 0. The number
-refers to the list of all the input subtitle streams. If it is greater
-than the number of subtitle streams minus one, then the last one is
-selected, if it is negative the subtitle rendering is disabled.
+@item -ast @var{audio_stream_specifier}
+Select the desired audio stream using the given stream specifier. The stream
+specifiers are described in the @ref{Stream specifiers} chapter. If this option
+is not specified, the "best" audio stream is selected in the program of the
+already selected video stream.
+@item -vst @var{video_stream_specifier}
+Select the desired video stream using the given stream specifier. The stream
+specifiers are described in the @ref{Stream specifiers} chapter. If this option
+is not specified, the "best" video stream is selected.
+@item -sst @var{subtitle_stream_specifier}
+Select the desired subtitle stream using the given stream specifier. The stream
+specifiers are described in the @ref{Stream specifiers} chapter. If this option
+is not specified, the "best" subtitle stream is selected in the program of the
+already selected video or audio stream.
@item -autoexit
Exit when video is done playing.
@item -exitonkeydown
diff --git a/ffplay.c b/ffplay.c
index bd156df..655af6d 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -312,11 +312,7 @@ static int screen_height = 0;
static int audio_disable;
static int video_disable;
static int subtitle_disable;
-static int wanted_stream[AVMEDIA_TYPE_NB] = {
- [AVMEDIA_TYPE_AUDIO] = -1,
- [AVMEDIA_TYPE_VIDEO] = -1,
- [AVMEDIA_TYPE_SUBTITLE] = -1,
-};
+static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
static int seek_by_bytes = -1;
static int display_disable;
static int show_status = 1;
@@ -2963,22 +2959,35 @@ static int read_thread(void *arg)
is->realtime = is_realtime(ic);
- for (i = 0; i < ic->nb_streams; i++)
- ic->streams[i]->discard = AVDISCARD_ALL;
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVStream *st = ic->streams[i];
+ enum AVMediaType type = st->codec->codec_type;
+ st->discard = AVDISCARD_ALL;
+ if (wanted_stream_spec[type] && st_index[type] == -1)
+ if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
+ st_index[type] = i;
+ }
+ for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
+ if (wanted_stream_spec[i] && st_index[i] == -1) {
+ av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
+ st_index[i] = INT_MAX;
+ }
+ }
+
if (!video_disable)
st_index[AVMEDIA_TYPE_VIDEO] =
av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
- wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
+ st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
if (!audio_disable)
st_index[AVMEDIA_TYPE_AUDIO] =
av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
- wanted_stream[AVMEDIA_TYPE_AUDIO],
+ st_index[AVMEDIA_TYPE_AUDIO],
st_index[AVMEDIA_TYPE_VIDEO],
NULL, 0);
if (!video_disable && !subtitle_disable)
st_index[AVMEDIA_TYPE_SUBTITLE] =
av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
- wanted_stream[AVMEDIA_TYPE_SUBTITLE],
+ st_index[AVMEDIA_TYPE_SUBTITLE],
(st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
st_index[AVMEDIA_TYPE_AUDIO] :
st_index[AVMEDIA_TYPE_VIDEO]),
@@ -3669,9 +3678,9 @@ static const OptionDef options[] = {
{ "an", OPT_BOOL, { &audio_disable }, "disable audio" },
{ "vn", OPT_BOOL, { &video_disable }, "disable video" },
{ "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
- { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
- { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
- { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
+ { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
+ { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
+ { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
{ "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
{ "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
{ "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
OpenPOWER on IntegriCloud