ffplay: add support for toggling between multiple video filters with the w key
Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
		
							parent
							
								
									affc41047e
								
							
						
					
					
						commit
						a583e2bebe
					
				@ -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.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								ffplay.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								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"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user