diff --git a/CMakeLists.txt b/CMakeLists.txt
index 151a7a389465d748fd271776c6a45c9079d2af9b..de4b96ceb84dcc018daa8b3ed5193a3a79e51123 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -132,6 +132,7 @@ if("${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 	find_package(SDL2 REQUIRED)
 	find_package(CURL REQUIRED)
 	find_package(GME REQUIRED)
+	find_package(VPX REQUIRED)
 endif()
 
 if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
diff --git a/cmake/Modules/FindVPX.cmake b/cmake/Modules/FindVPX.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..f47aee65faad13ed21addcef20db5f096dff3d45
--- /dev/null
+++ b/cmake/Modules/FindVPX.cmake
@@ -0,0 +1,33 @@
+include(LibFindMacros)
+
+libfind_pkg_check_modules(VPX_PKGCONF VPX)
+
+find_path(VPX_INCLUDE_DIR
+	NAMES vpx/vp8.h
+	PATHS
+		${VPX_PKGCONF_INCLUDE_DIRS}
+		"/usr/include"
+		"/usr/local/include"
+)
+
+find_library(VPX_LIBRARY
+	NAMES vpx
+	PATHS
+		${VPX_PKGCONF_LIBRARY_DIRS}
+		"/usr/lib"
+		"/usr/local/lib"
+)
+
+set(VPX_PROCESS_INCLUDES VPX_INCLUDE_DIR)
+set(VPX_PROCESS_LIBS VPX_LIBRARY)
+libfind_process(VPX)
+
+if(VPX_FOUND AND NOT TARGET webm::libvpx)
+	add_library(webm::libvpx UNKNOWN IMPORTED)
+	set_target_properties(
+		webm::libvpx
+		PROPERTIES
+		IMPORTED_LOCATION "${VPX_LIBRARY}"
+		INTERFACE_INCLUDE_DIRECTORIES "${VPX_INCLUDE_DIR}"
+	)
+endif()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ac592f89d71b989717084389fb08f371d92e1602..7cd3db33db288abbe70909c5d4175c1375a77ea8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -229,6 +229,8 @@ target_link_libraries(SRB2SDL2 PRIVATE xmp-lite::xmp-lite)
 target_link_libraries(SRB2SDL2 PRIVATE glad::glad)
 target_link_libraries(SRB2SDL2 PRIVATE fmt)
 target_link_libraries(SRB2SDL2 PRIVATE imgui::imgui)
+target_link_libraries(SRB2SDL2 PRIVATE webm::libwebm webm::libvpx)
+target_link_libraries(SRB2SDL2 PRIVATE libyuv::libyuv)
 
 target_link_libraries(SRB2SDL2 PRIVATE acsvm)
 
diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt
index 479fd26a95e442bdd640ce75f1f9c4ad70a4942f..d4cad6bbaa11b31155240d225115e4f90e2b53ad 100644
--- a/thirdparty/CMakeLists.txt
+++ b/thirdparty/CMakeLists.txt
@@ -15,6 +15,7 @@ include("cpm-sdl2.cmake")
 	include("cpm-png.cmake")
 	include("cpm-curl.cmake")
 	include("cpm-libgme.cmake")
+	include("cpm-libvpx.cmake")
 endif()
 
 include("cpm-rapidjson.cmake")
@@ -23,6 +24,8 @@ include("cpm-xmp-lite.cmake")
 include("cpm-fmt.cmake")
 include("cpm-imgui.cmake")
 include("cpm-acsvm.cmake")
+include("cpm-libwebm.cmake")
+include("cpm-libyuv.cmake")
 
 add_subdirectory(tcbrindle_span)
 add_subdirectory(stb_vorbis)
diff --git a/thirdparty/cpm-libvpx.cmake b/thirdparty/cpm-libvpx.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..022f133ca959fcaf1af54a5007c1a5db3e3b219f
--- /dev/null
+++ b/thirdparty/cpm-libvpx.cmake
@@ -0,0 +1,37 @@
+CPMAddPackage(
+	NAME libvpx
+	VERSION 1.12.0
+	URL "https://chromium.googlesource.com/webm/libvpx/+archive/03265cd42b3783532de72f2ded5436652e6f5ce3.tar.gz"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY YES
+)
+
+if(libvpx_ADDED)
+	include(ExternalProject)
+
+	# libvpx configure script does CPU detection. So lets just
+	# call it instead of trying to do all that in CMake.
+	ExternalProject_Add(libvpx
+		PREFIX "${libvpx_BINARY_DIR}"
+		SOURCE_DIR "${libvpx_SOURCE_DIR}"
+		BINARY_DIR "${libvpx_BINARY_DIR}"
+		CONFIGURE_COMMAND sh "${libvpx_SOURCE_DIR}/configure"
+		--enable-vp8 --disable-vp9 --disable-vp8-decoder
+		--disable-examples --disable-tools --disable-docs
+		--disable-webm-io --disable-libyuv --disable-unit-tests
+		BUILD_COMMAND "make"
+		BUILD_BYPRODUCTS "${libvpx_BINARY_DIR}/libvpx.a"
+		INSTALL_COMMAND ""
+		USES_TERMINAL_CONFIGURE ON
+		USES_TERMINAL_BUILD ON
+	)
+
+	add_library(webm::libvpx STATIC IMPORTED GLOBAL)
+	add_dependencies(webm::libvpx libvpx)
+	set_target_properties(
+		webm::libvpx
+		PROPERTIES
+		IMPORTED_LOCATION "${libvpx_BINARY_DIR}/libvpx.a"
+		INTERFACE_INCLUDE_DIRECTORIES "${libvpx_SOURCE_DIR}"
+	)
+endif()
diff --git a/thirdparty/cpm-libwebm.cmake b/thirdparty/cpm-libwebm.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0b6bf4f0a2e1e3c1457c9a5113379187afc5b361
--- /dev/null
+++ b/thirdparty/cpm-libwebm.cmake
@@ -0,0 +1,31 @@
+CPMAddPackage(
+	NAME libwebm
+	VERSION 1.0.0.29
+	URL "https://chromium.googlesource.com/webm/libwebm/+archive/2f9fc054ab9547ca06071ec68dab9d54960abb2e.tar.gz"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY YES
+)
+
+if(libwebm_ADDED)
+	set(libwebm_SOURCES
+
+		common/file_util.cc
+		common/file_util.h
+		common/hdr_util.cc
+		common/hdr_util.h
+		common/webmids.h
+
+		mkvmuxer/mkvmuxer.cc
+		mkvmuxer/mkvmuxer.h
+		mkvmuxer/mkvmuxertypes.h
+		mkvmuxer/mkvmuxerutil.cc
+		mkvmuxer/mkvmuxerutil.h
+		mkvmuxer/mkvwriter.cc
+		mkvmuxer/mkvwriter.h
+	)
+	list(TRANSFORM libwebm_SOURCES PREPEND "${libwebm_SOURCE_DIR}/")
+	add_library(webm STATIC ${libwebm_SOURCES})
+	target_include_directories(webm PUBLIC "${libwebm_SOURCE_DIR}")
+	target_compile_features(webm PRIVATE cxx_std_11)
+	add_library(webm::libwebm ALIAS webm)
+endif()
diff --git a/thirdparty/cpm-libyuv.cmake b/thirdparty/cpm-libyuv.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..30cc925d6e6a56d6db9a4456132c190ceb9683d2
--- /dev/null
+++ b/thirdparty/cpm-libyuv.cmake
@@ -0,0 +1,77 @@
+CPMAddPackage(
+	NAME libyuv
+	VERSION 0
+	URL "https://chromium.googlesource.com/libyuv/libyuv/+archive/b2528b0be934de1918e20c85fc170d809eeb49ab.tar.gz"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY YES
+)
+
+if(libyuv_ADDED)
+	set(libyuv_SOURCES
+
+    # Headers
+    include/libyuv.h
+    include/libyuv/basic_types.h
+    include/libyuv/compare.h
+    include/libyuv/convert.h
+    include/libyuv/convert_argb.h
+    include/libyuv/convert_from.h
+    include/libyuv/convert_from_argb.h
+    include/libyuv/cpu_id.h
+    include/libyuv/mjpeg_decoder.h
+    include/libyuv/planar_functions.h
+    include/libyuv/rotate.h
+    include/libyuv/rotate_argb.h
+    include/libyuv/rotate_row.h
+    include/libyuv/row.h
+    include/libyuv/scale.h
+    include/libyuv/scale_argb.h
+    include/libyuv/scale_rgb.h
+    include/libyuv/scale_row.h
+    include/libyuv/scale_uv.h
+    include/libyuv/version.h
+    include/libyuv/video_common.h
+
+    # Source Files
+    source/compare.cc
+    source/compare_common.cc
+    source/compare_gcc.cc
+    source/compare_win.cc
+    source/convert.cc
+    source/convert_argb.cc
+    source/convert_from.cc
+    source/convert_from_argb.cc
+    source/convert_jpeg.cc
+    source/convert_to_argb.cc
+    source/convert_to_i420.cc
+    source/cpu_id.cc
+    source/mjpeg_decoder.cc
+    source/mjpeg_validate.cc
+    source/planar_functions.cc
+    source/rotate.cc
+    source/rotate_any.cc
+    source/rotate_argb.cc
+    source/rotate_common.cc
+    source/rotate_gcc.cc
+    source/rotate_win.cc
+    source/row_any.cc
+    source/row_common.cc
+    source/row_gcc.cc
+    source/row_win.cc
+    source/scale.cc
+    source/scale_any.cc
+    source/scale_argb.cc
+    source/scale_common.cc
+    source/scale_gcc.cc
+    source/scale_rgb.cc
+    source/scale_uv.cc
+    source/scale_win.cc
+    source/video_common.cc
+	)
+	list(TRANSFORM libyuv_SOURCES PREPEND "${libyuv_SOURCE_DIR}/")
+	add_library(yuv STATIC ${libyuv_SOURCES})
+
+	target_include_directories(yuv PUBLIC "${libyuv_SOURCE_DIR}/include")
+
+	add_library(libyuv::libyuv ALIAS yuv)
+endif()