diff --git a/etc/SuperBuild/CMakeLists.txt b/etc/SuperBuild/CMakeLists.txt index 50cc6374e..c8d149fbc 100644 --- a/etc/SuperBuild/CMakeLists.txt +++ b/etc/SuperBuild/CMakeLists.txt @@ -21,6 +21,7 @@ set(TLRENDER_PNG TRUE CACHE BOOL "Enable support for PNG") set(TLRENDER_EXR TRUE CACHE BOOL "Enable support for OpenEXR") set(TLRENDER_FFMPEG TRUE CACHE BOOL "Enable support for FFmpeg (see the README for how to build FFmpeg on Windows)") set(TLRENDER_FFMPEG_MINIMAL FALSE CACHE BOOL "Enable a minimal set of FFmpeg codecs") +set(TLRENDER_AV1 FALSE CACHE BOOL "Enable support for AV1 codec through FFmpeg") set(TLRENDER_VPX FALSE CACHE BOOL "Enable support for VPX codec through FFmpeg") set(TLRENDER_X264 FALSE CACHE BOOL "Enable support for x264 saving codec through FFmpeg") set(TLRENDER_YASM FALSE CACHE BOOL "Enable compiling YASM") @@ -142,6 +143,10 @@ endif() if(TLRENDER_X264 AND TLRENDER_FFMPEG AND NOT WIN32) list(APPEND TLRENDER_EXTERNAL_DEPS X264) endif() +if(TLRENDER_AV1 AND TLRENDER_FFMPEG AND NOT WIN32) + list(APPEND TLRENDER_EXTERNAL_DEPS dav1d) + list(APPEND TLRENDER_EXTERNAL_DEPS SvtAV1) +endif() if(TLRENDER_FFMPEG AND NOT WIN32) list(APPEND TLRENDER_EXTERNAL_DEPS FFmpeg) endif() diff --git a/etc/SuperBuild/cmake/Modules/BuildFFmpeg.cmake b/etc/SuperBuild/cmake/Modules/BuildFFmpeg.cmake index 2f26fd83f..c9151e188 100644 --- a/etc/SuperBuild/cmake/Modules/BuildFFmpeg.cmake +++ b/etc/SuperBuild/cmake/Modules/BuildFFmpeg.cmake @@ -16,16 +16,31 @@ else() if(TLRENDER_VPX) list(APPEND FFmpeg_LDFLAGS - --extra-ldflags="-L${CMAKE_INSTALL_PREFIX}/lib/" --extra-ldflags="${CMAKE_INSTALL_PREFIX}/lib/libvpx.a") list(APPEND FFmpeg_DEPS VPX) endif() + if(TLRENDER_AV1) + list(APPEND FFmpeg_LDFLAGS + --extra-ldflags="${CMAKE_INSTALL_PREFIX}/lib/libdav1d.a") + if(EXISTS ${CMAKE_INSTALL_PREFIX}/lib64/libSvtAv1Enc.a) + list(APPEND FFmpeg_LDFLAGS + --extra-ldflags="${CMAKE_INSTALL_PREFIX}/lib64/libSvtAv1Enc.a") + else() + list(APPEND FFmpeg_LDFLAGS + --extra-ldflags="${CMAKE_INSTALL_PREFIX}/lib/libSvtAv1Enc.a") + endif() + if (UNIX AND NOT APPLE) + list(APPEND FFmpeg_LDFLAGS + --extra-libs=-lm + --extra-libs=-lpthread) + endif() + list(APPEND FFmpeg_DEPS SvtAV1 dav1d) + endif() if(TLRENDER_X264) # # Make sure we pick the static libx264 we compiled, not the system one # list(APPEND FFmpeg_LDFLAGS - --extra-ldflags="-L${CMAKE_INSTALL_PREFIX}/lib/" --extra-ldflags="${CMAKE_INSTALL_PREFIX}/lib/libx264.a") list(APPEND FFmpeg_DEPS X264) endif() @@ -55,6 +70,7 @@ else() endif() set(FFmpeg_CONFIGURE_ARGS --prefix=${CMAKE_INSTALL_PREFIX} + --pkg-config-flags=--static --disable-programs --disable-doc --disable-postproc @@ -327,6 +343,11 @@ else() list(APPEND FFmpeg_CONFIGURE_ARGS --enable-libvpx) endif() + if(TLRENDER_AV1) + list(APPEND FFmpeg_CONFIGURE_ARGS + --enable-libdav1d + --enable-libsvtav1) + endif() if(TLRENDER_X264) list(APPEND FFmpeg_CONFIGURE_ARGS --enable-libx264 --enable-gpl) @@ -348,7 +369,7 @@ else() --assert-level=2) endif() - set(FFmpeg_CONFIGURE ./configure ${FFmpeg_CONFIGURE_ARGS}) + set(FFmpeg_CONFIGURE ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/lib64/pkgconfig:${CMAKE_INSTALL_PREFIX}/lib/pkgconfig -- ./configure ${FFmpeg_CONFIGURE_ARGS}) set(FFmpeg_BUILD make -j 4) set(FFmpeg_INSTALL make install) diff --git a/etc/SuperBuild/cmake/Modules/BuildSvtAV1.cmake b/etc/SuperBuild/cmake/Modules/BuildSvtAV1.cmake new file mode 100644 index 000000000..446a459dd --- /dev/null +++ b/etc/SuperBuild/cmake/Modules/BuildSvtAV1.cmake @@ -0,0 +1,21 @@ +include(ExternalProject) + + +set(SvtAV1_TAG v1.8.0) +set(SvtAV1_ARGS ${TLRENDER_EXTERNAL_ARGS}) + +list(APPEND SvtAV1_ARGS + -DENABLE_NASM=ON + ) + + +ExternalProject_Add( + SvtAV1 + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/SvtAV1 + DEPENDS NASM + GIT_REPOSITORY "https://gitlab.com/AOMediaCodec/SVT-AV1.git" + GIT_TAG ${SvtAV1_TAG} + LIST_SEPARATOR | + CMAKE_ARGS ${SvtAV1_ARGS} + ) + diff --git a/etc/SuperBuild/cmake/Modules/Builddav1d.cmake b/etc/SuperBuild/cmake/Modules/Builddav1d.cmake new file mode 100644 index 000000000..d4cf5f924 --- /dev/null +++ b/etc/SuperBuild/cmake/Modules/Builddav1d.cmake @@ -0,0 +1,21 @@ +include(ExternalProject) + + +set(dav1d_TAG 1.3.0) + +set(dav1d_CONFIGURE ${CMAKE_COMMAND} -E env PYTHONPATH="" -- meson setup -Denable_tools=false -Denable_tests=false --default-library=static -Dlibdir=${CMAKE_INSTALL_PREFIX}/lib --prefix=${CMAKE_INSTALL_PREFIX} build) +set(dav1d_BUILD export PYTHONPATH="" && cd build && ninja) +set(dav1d_INSTALL export PYTHONPATH="" && cd build && ninja install) + +ExternalProject_Add( + dav1d + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dav1d + DEPENDS NASM + GIT_REPOSITORY "https://code.videolan.org/videolan/dav1d.git" + GIT_TAG ${dav1d_TAG} + CONFIGURE_COMMAND ${dav1d_CONFIGURE} + BUILD_COMMAND ${dav1d_BUILD} + INSTALL_COMMAND ${dav1d_INSTALL} + BUILD_IN_SOURCE 1 +) + diff --git a/lib/tlIO/FFmpeg.cpp b/lib/tlIO/FFmpeg.cpp index c6637a867..e3c593d82 100644 --- a/lib/tlIO/FFmpeg.cpp +++ b/lib/tlIO/FFmpeg.cpp @@ -35,7 +35,8 @@ namespace tl "ProRes_HQ", "ProRes_4444", "ProRes_XQ", - "VP9"); + "VP9", + "AV1"); TLRENDER_ENUM_SERIALIZE_IMPL(Profile); TLRENDER_ENUM_IMPL( diff --git a/lib/tlIO/FFmpeg.h b/lib/tlIO/FFmpeg.h index b8adb10ce..91d23094b 100644 --- a/lib/tlIO/FFmpeg.h +++ b/lib/tlIO/FFmpeg.h @@ -34,7 +34,8 @@ namespace tl ProRes_4444, ProRes_XQ, VP9, - + AV1, + Count }; TLRENDER_ENUM(Profile); diff --git a/lib/tlIO/FFmpegReadVideo.cpp b/lib/tlIO/FFmpegReadVideo.cpp index 0d4c76b7d..c2e2f161b 100644 --- a/lib/tlIO/FFmpegReadVideo.cpp +++ b/lib/tlIO/FFmpegReadVideo.cpp @@ -134,6 +134,16 @@ namespace tl throw std::runtime_error(string::Format("{0}: {1}").arg(fileName).arg(getErrorLabel(r))); } _avCodecContext[_avStream]->thread_count = options.threadCount; + _avCodecContext[_avStream]->thread_type = FF_THREAD_FRAME; + + // libdav1d codec does not decode properly when thread count is + // 0. We must set it to 1. + if (avVideoCodecParameters->codec_id == AV_CODEC_ID_AV1 && + options.threadCount == 0) + { + _avCodecContext[_avStream]->thread_count = 1; + } + _avCodecContext[_avStream]->thread_type = FF_THREAD_FRAME; r = avcodec_open2(_avCodecContext[_avStream], avVideoCodec, 0); if (r < 0) diff --git a/lib/tlIO/FFmpegWrite.cpp b/lib/tlIO/FFmpegWrite.cpp index b387978a6..837a3552b 100644 --- a/lib/tlIO/FFmpegWrite.cpp +++ b/lib/tlIO/FFmpegWrite.cpp @@ -606,6 +606,9 @@ namespace tl avCodecID = AV_CODEC_ID_VP9; avProfile = FF_PROFILE_VP9_0; break; + case Profile::AV1: + avCodecID = AV_CODEC_ID_AV1; + break; default: break; }