diff --git a/Makefile b/Makefile
index 6de5a3d145f16630143cdb2aa0cec59773bea395..3007da50f765fd4674932bd18fcb4d520fe08e70 100644
--- a/Makefile
+++ b/Makefile
@@ -15,31 +15,6 @@ vpath %.cu   $(SRC_PATH)
 vpath %.ptx  $(SRC_PATH)
 vpath %/fate_config.sh.template $(SRC_PATH)
 
-AVPROGS-$(CONFIG_FFMPEG)   += ffmpeg
-AVPROGS-$(CONFIG_FFPLAY)   += ffplay
-AVPROGS-$(CONFIG_FFPROBE)  += ffprobe
-AVPROGS-$(CONFIG_FFSERVER) += ffserver
-
-AVPROGS    := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
-INSTPROGS   = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
-PROGS      += $(AVPROGS)
-
-AVBASENAMES  = ffmpeg ffplay ffprobe ffserver
-ALLAVPROGS   = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
-ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
-
-$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
-$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_opencl.o))
-
-OBJS-ffmpeg                   += ffmpeg_opt.o ffmpeg_filter.o ffmpeg_hw.o
-OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
-OBJS-ffmpeg-$(CONFIG_LIBMFX)  += ffmpeg_qsv.o
-ifndef CONFIG_VIDEOTOOLBOX
-OBJS-ffmpeg-$(CONFIG_VDA)     += ffmpeg_videotoolbox.o
-endif
-OBJS-ffmpeg-$(CONFIG_CUVID)   += ffmpeg_cuvid.o
-OBJS-ffserver                 += ffserver_config.o
-
 TESTTOOLS   = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
 HOSTPROGS  := $(TESTTOOLS:%=tests/%) doc/print_options
 
@@ -69,8 +44,6 @@ FF_EXTRALIBS := $(FFEXTRALIBS)
 FF_DEP_LIBS  := $(DEP_LIBS)
 FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
 
-all: $(AVPROGS)
-
 $(TOOLS): %$(EXESUF): %.o
 	$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS)
 
@@ -117,27 +90,17 @@ endef
 
 $(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
 
+include $(SRC_PATH)/fftools/Makefile
 include $(SRC_PATH)/doc/Makefile
 include $(SRC_PATH)/doc/examples/Makefile
 
-define DOPROG
-OBJS-$(1) += $(1).o $(OBJS-$(1)-yes)
-$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
-$$(OBJS-$(1)): CFLAGS  += $(CFLAGS-$(1))
-$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
-$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1))
--include $$(OBJS-$(1):.o=.d)
-endef
-
-$(foreach P,$(AVPROGS-yes),$(eval $(call DOPROG,$(P))))
-
-ffprobe.o cmdutils.o libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h
+libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h
 
 $(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
 	$(CP) $< $@
 	$(STRIP) $@
 
-%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
+%$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS)
 	$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
 
 VERSION_SH  = $(SRC_PATH)/ffbuild/version.sh
@@ -153,37 +116,22 @@ libavutil/ffversion.h .version:
 # force version.sh to run whenever version might have changed
 -include .version
 
-ifdef AVPROGS
-install: install-progs install-data
-endif
-
 install: install-libs install-headers
 
 install-libs: install-libs-yes
 
-install-progs-yes:
-install-progs-$(CONFIG_SHARED): install-libs
-
-install-progs: install-progs-yes $(AVPROGS)
-	$(Q)mkdir -p "$(BINDIR)"
-	$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
-
 install-data: $(DATA_FILES) $(EXAMPLES_FILES) $(EXAMPLE_MAKEFILE)
 	$(Q)mkdir -p "$(DATADIR)/examples"
 	$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
 	$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
 	$(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile"
 
-uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
-
-uninstall-progs:
-	$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
+uninstall: uninstall-libs uninstall-headers uninstall-data
 
 uninstall-data:
 	$(RM) -r "$(DATADIR)"
 
 clean::
-	$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
 	$(RM) $(CLEANSUFFIXES)
 	$(RM) $(CLEANSUFFIXES:%=compat/msvcrt/%)
 	$(RM) $(CLEANSUFFIXES:%=compat/atomics/pthread/%)
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index f0c4f7969e6f3fdbf63586849a75a7d300bbb848..ff958d33c61970f414ed43d2e6ffe4b25a51be1f 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -30,7 +30,7 @@ EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examp
 EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile
 
 $(foreach P,$(DOC_EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o))
-$(DOC_EXAMPLES): %$(PROGSSUF)$(EXESUF): %.o
+$(DOC_EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o
 
 examples: $(DOC_EXAMPLES)
 
diff --git a/fftools/Makefile b/fftools/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..094f6d6265a1a124139ab1fa65fdda50b2e7431a
--- /dev/null
+++ b/fftools/Makefile
@@ -0,0 +1,57 @@
+AVPROGS-$(CONFIG_FFMPEG)   += ffmpeg
+AVPROGS-$(CONFIG_FFPLAY)   += ffplay
+AVPROGS-$(CONFIG_FFPROBE)  += ffprobe
+AVPROGS-$(CONFIG_FFSERVER) += ffserver
+
+AVPROGS     := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
+PROGS       += $(AVPROGS)
+
+AVBASENAMES  = ffmpeg ffplay ffprobe ffserver
+ALLAVPROGS   = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
+ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
+
+OBJS-ffmpeg                        += fftools/ffmpeg_opt.o fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o
+OBJS-ffmpeg-$(CONFIG_CUVID)        += fftools/ffmpeg_cuvid.o
+OBJS-ffmpeg-$(CONFIG_LIBMFX)       += fftools/ffmpeg_qsv.o
+ifndef CONFIG_VIDEOTOOLBOX
+OBJS-ffmpeg-$(CONFIG_VDA)          += fftools/ffmpeg_videotoolbox.o
+endif
+OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += fftools/ffmpeg_videotoolbox.o
+OBJS-ffserver                      += fftools/ffserver_config.o
+
+define DOFFTOOL
+OBJS-$(1)-$(CONFIG_OPENCL) += fftools/cmdutils_opencl.o
+OBJS-$(1) += fftools/cmdutils.o fftools/$(1).o $(OBJS-$(1)-yes)
+$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
+$$(OBJS-$(1)): | fftools
+$$(OBJS-$(1)): CFLAGS  += $(CFLAGS-$(1))
+$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
+$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1))
+-include $$(OBJS-$(1):.o=.d)
+endef
+
+$(foreach P,$(AVPROGS-yes),$(eval $(call DOFFTOOL,$(P))))
+
+all: $(AVPROGS)
+
+fftools/ffprobe.o fftools/cmdutils.o: libavutil/ffversion.h | fftools
+OBJDIRS += fftools
+
+ifdef AVPROGS
+install: install-progs install-data
+endif
+
+install-progs-yes:
+install-progs-$(CONFIG_SHARED): install-libs
+
+install-progs: install-progs-yes $(AVPROGS)
+	$(Q)mkdir -p "$(BINDIR)"
+	$(INSTALL) -c -m 755 $(AVPROGS) "$(BINDIR)"
+
+uninstall: uninstall-progs
+
+uninstall-progs:
+	$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
+
+clean::
+	$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G) $(CLEANSUFFIXES:%=fftools/%)
diff --git a/cmdutils.c b/fftools/cmdutils.c
similarity index 100%
rename from cmdutils.c
rename to fftools/cmdutils.c
diff --git a/cmdutils.h b/fftools/cmdutils.h
similarity index 99%
rename from cmdutils.h
rename to fftools/cmdutils.h
index e1d64d89869ca8cd74ba960aeabc6e5ac2cac43a..2997ee37b5afe4be5495a6f755fac58e5092d4e2 100644
--- a/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -19,8 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef CMDUTILS_H
-#define CMDUTILS_H
+#ifndef FFTOOLS_CMDUTILS_H
+#define FFTOOLS_CMDUTILS_H
 
 #include <stdint.h>
 
@@ -659,4 +659,4 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
 
 double get_rotation(AVStream *st);
 
-#endif /* CMDUTILS_H */
+#endif /* FFTOOLS_CMDUTILS_H */
diff --git a/cmdutils_opencl.c b/fftools/cmdutils_opencl.c
similarity index 100%
rename from cmdutils_opencl.c
rename to fftools/cmdutils_opencl.c
diff --git a/ffmpeg.c b/fftools/ffmpeg.c
similarity index 100%
rename from ffmpeg.c
rename to fftools/ffmpeg.c
diff --git a/ffmpeg.h b/fftools/ffmpeg.h
similarity index 99%
rename from ffmpeg.h
rename to fftools/ffmpeg.h
index d2deb432b79f06cf209aba39a2f9cf3673023f1e..f6c76bcc553c6f16ed54d197fc0f4a5a166265f1 100644
--- a/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -16,8 +16,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef FFMPEG_H
-#define FFMPEG_H
+#ifndef FFTOOLS_FFMPEG_H
+#define FFTOOLS_FFMPEG_H
 
 #include "config.h"
 
@@ -676,4 +676,4 @@ int hw_device_setup_for_encode(OutputStream *ost);
 
 int hwaccel_decode_init(AVCodecContext *avctx);
 
-#endif /* FFMPEG_H */
+#endif /* FFTOOLS_FFMPEG_H */
diff --git a/ffmpeg_cuvid.c b/fftools/ffmpeg_cuvid.c
similarity index 100%
rename from ffmpeg_cuvid.c
rename to fftools/ffmpeg_cuvid.c
diff --git a/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
similarity index 100%
rename from ffmpeg_filter.c
rename to fftools/ffmpeg_filter.c
diff --git a/ffmpeg_hw.c b/fftools/ffmpeg_hw.c
similarity index 100%
rename from ffmpeg_hw.c
rename to fftools/ffmpeg_hw.c
diff --git a/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
similarity index 100%
rename from ffmpeg_opt.c
rename to fftools/ffmpeg_opt.c
diff --git a/ffmpeg_qsv.c b/fftools/ffmpeg_qsv.c
similarity index 100%
rename from ffmpeg_qsv.c
rename to fftools/ffmpeg_qsv.c
diff --git a/ffmpeg_videotoolbox.c b/fftools/ffmpeg_videotoolbox.c
similarity index 100%
rename from ffmpeg_videotoolbox.c
rename to fftools/ffmpeg_videotoolbox.c
diff --git a/ffplay.c b/fftools/ffplay.c
similarity index 100%
rename from ffplay.c
rename to fftools/ffplay.c
diff --git a/ffprobe.c b/fftools/ffprobe.c
similarity index 100%
rename from ffprobe.c
rename to fftools/ffprobe.c
diff --git a/ffserver.c b/fftools/ffserver.c
similarity index 100%
rename from ffserver.c
rename to fftools/ffserver.c
diff --git a/ffserver_config.c b/fftools/ffserver_config.c
similarity index 100%
rename from ffserver_config.c
rename to fftools/ffserver_config.c
diff --git a/ffserver_config.h b/fftools/ffserver_config.h
similarity index 98%
rename from ffserver_config.h
rename to fftools/ffserver_config.h
index 48d38dc3250b313cbdbe1bd31640ec167b992f7b..089b8484da3108abe4753f60386a1abc7dec77a6 100644
--- a/ffserver_config.h
+++ b/fftools/ffserver_config.h
@@ -18,8 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef FFSERVER_CONFIG_H
-#define FFSERVER_CONFIG_H
+#ifndef FFTOOLS_FFSERVER_CONFIG_H
+#define FFTOOLS_FFSERVER_CONFIG_H
 
 #define FFM_PACKET_SIZE 4096
 
@@ -152,4 +152,4 @@ int ffserver_parse_ffconfig(const char *filename, FFServerConfig *config);
 
 void ffserver_free_child_args(void *argsp);
 
-#endif /* FFSERVER_CONFIG_H */
+#endif /* FFTOOLS_FFSERVER_CONFIG_H */