From ae6fe159f2990c3c0921805a932b7772906a8df4 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 10 May 2014 13:20:56 +0200 Subject: [PATCH 1/6] ffplay: increase AV_SYNC_THRESHOLD_MIN to 0.04 Less than 0.04 sec delays should not be noticable, and it helps us with 50fps content where some timing errors can cause a frame dup where it is not really necessary. Signed-off-by: Marton Balint --- ffplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index 86b9126ab2..588aff58f6 100644 --- a/ffplay.c +++ b/ffplay.c @@ -72,7 +72,7 @@ const int program_birth_year = 2003; #define SDL_AUDIO_BUFFER_SIZE 1024 /* no AV sync correction is done if below the minimum AV sync threshold */ -#define AV_SYNC_THRESHOLD_MIN 0.01 +#define AV_SYNC_THRESHOLD_MIN 0.04 /* AV sync correction is done if above the maximum AV sync threshold */ #define AV_SYNC_THRESHOLD_MAX 0.1 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */ From 1fab67b6851f64778aa0ad9087e2d14f9ef1a798 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 10 May 2014 13:27:09 +0200 Subject: [PATCH 2/6] ffplay: fix compilation with Visual Studio Based on a patch by achristensen from trac.ffmpeg.org. Partially fixes ticket #3580. Signed-off-by: Marton Balint --- ffplay.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index 588aff58f6..fabb48c9cf 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2824,7 +2824,10 @@ static int read_thread(void *arg) if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) { AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]]; AVCodecContext *avctx = st->codec; - VideoPicture vp = {.width = avctx->width, .height = avctx->height, .sar = av_guess_sample_aspect_ratio(ic, st, NULL)}; + VideoPicture vp = {0}; + vp.width = avctx->width; + vp.height = avctx->height; + vp.sar = av_guess_sample_aspect_ratio(ic, st, NULL); if (vp.width) set_default_window_size(&vp); } From e11697759d06900195136df2be035d0d052316a1 Mon Sep 17 00:00:00 2001 From: John Peebles Date: Fri, 16 May 2014 21:44:19 -0400 Subject: [PATCH 3/6] cmdutils: replace usages of "#ifdef __MINGW32__" with "#ifdef _WIN32" because MSVC only defines _WIN32 With the previous patch, this should fix ticket #3580 as well. Signed-off-by: John Peebles --- cmdutils.h | 2 +- ffplay.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmdutils.h b/cmdutils.h index 3fbaae93c2..c4a16aac73 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -30,7 +30,7 @@ #include "libavformat/avformat.h" #include "libswscale/swscale.h" -#ifdef __MINGW32__ +#ifdef _WIN32 #undef main /* We don't want SDL to override our main() */ #endif diff --git a/ffplay.c b/ffplay.c index fabb48c9cf..df7e870119 100644 --- a/ffplay.c +++ b/ffplay.c @@ -3635,7 +3635,7 @@ int main(int argc, char **argv) flags &= ~SDL_INIT_AUDIO; if (display_disable) SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */ -#if !defined(__MINGW32__) && !defined(__APPLE__) +#if !defined(_WIN32) && !defined(__APPLE__) flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */ #endif if (SDL_Init (flags)) { From 0c8d8c0c80671fd592697fee5ca7e645c26d2da9 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 10 May 2014 14:32:43 +0200 Subject: [PATCH 4/6] ffplay: try multiple sample rates if audio open fails Should fix ticket #3509. Signed-off-by: Marton Balint --- ffplay.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/ffplay.c b/ffplay.c index df7e870119..fbf7d56126 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2415,6 +2415,8 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb SDL_AudioSpec wanted_spec, spec; const char *env; static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6}; + static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000}; + int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1; env = SDL_getenv("SDL_AUDIO_CHANNELS"); if (env) { @@ -2425,24 +2427,32 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels); wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX; } - wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout); + wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout); + wanted_spec.channels = wanted_nb_channels; wanted_spec.freq = wanted_sample_rate; if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) { av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n"); return -1; } + while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq) + next_sample_rate_idx--; wanted_spec.format = AUDIO_S16SYS; wanted_spec.silence = 0; wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; wanted_spec.callback = sdl_audio_callback; wanted_spec.userdata = opaque; while (SDL_OpenAudio(&wanted_spec, &spec) < 0) { - av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError()); + av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n", + wanted_spec.channels, wanted_spec.freq, SDL_GetError()); wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)]; if (!wanted_spec.channels) { - av_log(NULL, AV_LOG_ERROR, - "No more channel combinations to try, audio open failed\n"); - return -1; + wanted_spec.freq = next_sample_rates[next_sample_rate_idx--]; + wanted_spec.channels = wanted_nb_channels; + if (!wanted_spec.freq) { + av_log(NULL, AV_LOG_ERROR, + "No more combinations to try, audio open failed\n"); + return -1; + } } wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels); } From affc41047e96bfe6026ec4e27ee9c1d30c5869b9 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 10 May 2014 14:59:28 +0200 Subject: [PATCH 5/6] ffplay: fix typo in docs Signed-off-by: Marton Balint --- doc/ffplay.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ffplay.texi b/doc/ffplay.texi index c26c68da5d..d600477586 100644 --- a/doc/ffplay.texi +++ b/doc/ffplay.texi @@ -174,7 +174,7 @@ Toggle full screen. Pause. @item a -Cycle audio channel in the curret program. +Cycle audio channel in the current program. @item v Cycle video channel. From a583e2bebe7746f7a68aede707ec3eebfd908659 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Mon, 6 Jan 2014 21:14:23 +0100 Subject: [PATCH 6/6] ffplay: add support for toggling between multiple video filters with the w key Signed-off-by: Marton Balint --- doc/ffplay.texi | 5 ++++- ffplay.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/doc/ffplay.texi b/doc/ffplay.texi index d600477586..3a03d36d04 100644 --- a/doc/ffplay.texi +++ b/doc/ffplay.texi @@ -84,6 +84,9 @@ output. In the filtergraph, the input is associated to the label ffmpeg-filters manual for more information about the filtergraph syntax. +You can specify this parameter multiple times and cycle through the specified +filtergraphs along with the show modes by pressing the key @key{w}. + @item -af @var{filtergraph} @var{filtergraph} is a description of the filtergraph to apply to the input audio. @@ -186,7 +189,7 @@ Cycle subtitle channel in the current program. Cycle program. @item w -Show audio waves. +Cycle video filters or show modes. @item s Step to the next frame. diff --git a/ffplay.c b/ffplay.c index fbf7d56126..e0653b33af 100644 --- a/ffplay.c +++ b/ffplay.c @@ -268,6 +268,7 @@ typedef struct VideoState { int step; #if CONFIG_AVFILTER + int vfilter_idx; AVFilterContext *in_video_filter; // the first filter in the video chain AVFilterContext *out_video_filter; // the last filter in the video chain AVFilterContext *in_audio_filter; // the first filter in the audio chain @@ -324,7 +325,8 @@ double rdftspeed = 0.02; static int64_t cursor_last_shown; static int cursor_hidden = 0; #if CONFIG_AVFILTER -static char *vfilters = NULL; +static const char **vfilters_list = NULL; +static int nb_vfilters = 0; static char *afilters = NULL; #endif @@ -339,6 +341,15 @@ static AVPacket flush_pkt; static SDL_Surface *screen; +#if CONFIG_AVFILTER +static int opt_add_vfilter(void *optctx, const char *opt, const char *arg) +{ + GROW_ARRAY(vfilters_list, nb_vfilters); + vfilters_list[nb_vfilters - 1] = arg; + return 0; +} +#endif + static inline int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1, enum AVSampleFormat fmt2, int64_t channel_count2) @@ -1051,7 +1062,7 @@ static void do_exit(VideoState *is) av_lockmgr_register(NULL); uninit_opts(); #if CONFIG_AVFILTER - av_freep(&vfilters); + av_freep(&vfilters_list); #endif avformat_network_deinit(); if (show_status) @@ -1919,6 +1930,7 @@ static int video_thread(void *arg) int last_h = 0; enum AVPixelFormat last_format = -2; int last_serial = -1; + int last_vfilter_idx = 0; #endif for (;;) { @@ -1937,7 +1949,8 @@ static int video_thread(void *arg) if ( last_w != frame->width || last_h != frame->height || last_format != frame->format - || last_serial != serial) { + || last_serial != serial + || last_vfilter_idx != is->vfilter_idx) { av_log(NULL, AV_LOG_DEBUG, "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n", last_w, last_h, @@ -1946,7 +1959,7 @@ static int video_thread(void *arg) (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial); avfilter_graph_free(&graph); graph = avfilter_graph_alloc(); - if ((ret = configure_video_filters(graph, is, vfilters, frame)) < 0) { + if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) { SDL_Event event; event.type = FF_QUIT_EVENT; event.user.data1 = is; @@ -1959,6 +1972,7 @@ static int video_thread(void *arg) last_h = frame->height; last_format = frame->format; last_serial = serial; + last_vfilter_idx = is->vfilter_idx; frame_rate = filt_out->inputs[0]->frame_rate; } @@ -3263,7 +3277,17 @@ static void event_loop(VideoState *cur_stream) stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE); break; case SDLK_w: +#if CONFIG_AVFILTER + if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) { + if (++cur_stream->vfilter_idx >= nb_vfilters) + cur_stream->vfilter_idx = 0; + } else { + cur_stream->vfilter_idx = 0; + toggle_audio_display(cur_stream); + } +#else toggle_audio_display(cur_stream); +#endif break; case SDLK_PAGEUP: if (cur_stream->ic->nb_chapters <= 1) { @@ -3529,7 +3553,7 @@ static const OptionDef options[] = { { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" }, { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" }, #if CONFIG_AVFILTER - { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "set video filters", "filter_graph" }, + { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" }, { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" }, #endif { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" }, @@ -3572,7 +3596,7 @@ void show_help_default(const char *opt, const char *arg) "v cycle video channel\n" "t cycle subtitle channel in the current program\n" "c cycle program\n" - "w show audio waves\n" + "w cycle video filters or show modes\n" "s activate frame-step mode\n" "left/right seek backward/forward 10 seconds\n" "down/up seek backward/forward 1 minute\n"