diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f2d0de2d..18dc98c01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,13 @@ cmake_minimum_required(VERSION 3.18) project(TorchCodec) +# Define LINUX platform variable globally +if (UNIX AND NOT APPLE) + set(LINUX TRUE) +else() + set(LINUX FALSE) +endif() + add_subdirectory(src/torchcodec/_core) diff --git a/src/torchcodec/__init__.py b/src/torchcodec/__init__.py index c0f4c2b6d..079db9824 100644 --- a/src/torchcodec/__init__.py +++ b/src/torchcodec/__init__.py @@ -4,6 +4,8 @@ # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. +from pathlib import Path + # Note: usort wants to put Frame and FrameBatch after decoders and samplers, # but that results in circular import. from ._frame import AudioSamples, Frame, FrameBatch # usort:skip # noqa @@ -14,3 +16,12 @@ from .version import __version__ # noqa: F401 except Exception: pass + +# cmake_prefix_path is needed for downstream cmake-based builds that use +# torchcodec as a dependency to tell cmake where torchcodec is installed and where to find its +# CMake configuration files. +# Pytorch itself has a similar mechanism which we use in our setup.py! +cmake_prefix_path = Path(__file__).parent / "share" / "cmake" +# Similarly, these are exposed for downstream builds that use torchcodec as a +# dependency. +from ._core import core_library_path, ffmpeg_major_version # usort:skip diff --git a/src/torchcodec/_core/CMakeLists.txt b/src/torchcodec/_core/CMakeLists.txt index 6b4ccb5d4..cecbf863a 100644 --- a/src/torchcodec/_core/CMakeLists.txt +++ b/src/torchcodec/_core/CMakeLists.txt @@ -245,16 +245,16 @@ if(DEFINED ENV{BUILD_AGAINST_ALL_FFMPEG_FROM_S3}) you still need a different FFmpeg to be installed for run time!" ) - # This will expose the ffmpeg4, ffmpeg5, ffmpeg6, ffmpeg7, and ffmpeg8 targets + # This will expose the torchcodec::ffmpeg{N} (N=4,5,6,7,8) targets include( ${CMAKE_CURRENT_SOURCE_DIR}/fetch_and_expose_non_gpl_ffmpeg_libs.cmake ) - make_torchcodec_libraries(8 ffmpeg8) - make_torchcodec_libraries(7 ffmpeg7) - make_torchcodec_libraries(6 ffmpeg6) - make_torchcodec_libraries(4 ffmpeg4) - make_torchcodec_libraries(5 ffmpeg5) + make_torchcodec_libraries(8 torchcodec::ffmpeg8) + make_torchcodec_libraries(7 torchcodec::ffmpeg7) + make_torchcodec_libraries(6 torchcodec::ffmpeg6) + make_torchcodec_libraries(4 torchcodec::ffmpeg4) + make_torchcodec_libraries(5 torchcodec::ffmpeg5) else() message( STATUS @@ -263,40 +263,12 @@ else() installed FFmpeg from conda, make sure pkg-config is installed from conda as well." ) - find_package(PkgConfig REQUIRED) - pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET - libavdevice - libavfilter - libavformat - libavcodec - libavutil - libswresample - libswscale - ) - # Split libavcodec's version string by '.' and convert it to a list - string(REPLACE "." ";" libavcodec_version_list ${LIBAV_libavcodec_VERSION}) - # Get the first element of the list, which is the major version - list(GET libavcodec_version_list 0 libavcodec_major_version) - - if (${libavcodec_major_version} STREQUAL "58") - set(ffmpeg_major_version "4") - elseif (${libavcodec_major_version} STREQUAL "59") - set(ffmpeg_major_version "5") - elseif (${libavcodec_major_version} STREQUAL "60") - set(ffmpeg_major_version "6") - elseif (${libavcodec_major_version} STREQUAL "61") - set(ffmpeg_major_version "7") - elseif (${libavcodec_major_version} STREQUAL "62") - set(ffmpeg_major_version "8") - else() - message( - FATAL_ERROR - "Unsupported libavcodec version: ${libavcodec_major_version}" - ) - endif() + # This will expose `add_ffmpeg_target_with_pkg_config` + include("${CMAKE_CURRENT_SOURCE_DIR}/../share/cmake/TorchCodec/ffmpeg_versions.cmake") - make_torchcodec_libraries(${ffmpeg_major_version} PkgConfig::LIBAV) + add_ffmpeg_target_with_pkg_config(ffmpeg_major_version) + make_torchcodec_libraries(${ffmpeg_major_version} torchcodec::ffmpeg${ffmpeg_major_version}) # Expose these values updwards so that the test compilation does not need # to re-figure it out. FIXME: it's not great that we just copy-paste the diff --git a/src/torchcodec/_core/__init__.py b/src/torchcodec/_core/__init__.py index 55ff697b3..add9efa90 100644 --- a/src/torchcodec/_core/__init__.py +++ b/src/torchcodec/_core/__init__.py @@ -19,6 +19,7 @@ _test_frame_pts_equality, add_audio_stream, add_video_stream, + core_library_path, create_from_bytes, create_from_file, create_from_file_like, @@ -29,6 +30,7 @@ encode_video_to_file, encode_video_to_file_like, encode_video_to_tensor, + ffmpeg_major_version, get_ffmpeg_library_versions, get_frame_at_index, get_frame_at_pts, diff --git a/src/torchcodec/_core/fetch_and_expose_non_gpl_ffmpeg_libs.cmake b/src/torchcodec/_core/fetch_and_expose_non_gpl_ffmpeg_libs.cmake index 07abd2e87..1200499dd 100644 --- a/src/torchcodec/_core/fetch_and_expose_non_gpl_ffmpeg_libs.cmake +++ b/src/torchcodec/_core/fetch_and_expose_non_gpl_ffmpeg_libs.cmake @@ -9,20 +9,12 @@ endif() include(FetchContent) -if (UNIX AND NOT APPLE) - set(LINUX TRUE) -else() - set(LINUX FALSE) -endif() - set( base_url https://pytorch.s3.amazonaws.com/torchcodec/ffmpeg/2025-03-14 ) if (LINUX) - set(lib_dir "lib") - set( platform_url ${base_url}/linux_x86_64 @@ -48,58 +40,7 @@ if (LINUX) f8_sha256 c55b3c1a4b5e4d5fdd7c632bea3ab6f45b4e37cc8e0999dda3f84a8ed8defad8 ) - set( - f4_library_file_names - libavutil.so.56 - libavcodec.so.58 - libavformat.so.58 - libavdevice.so.58 - libavfilter.so.7 - libswscale.so.5 - libswresample.so.3 - ) - set( - f5_library_file_names - libavutil.so.57 - libavcodec.so.59 - libavformat.so.59 - libavdevice.so.59 - libavfilter.so.8 - libswscale.so.6 - libswresample.so.4 - ) - set( - f6_library_file_names - libavutil.so.58 - libavcodec.so.60 - libavformat.so.60 - libavdevice.so.60 - libavfilter.so.9 - libswscale.so.7 - libswresample.so.4 - ) - set( - f7_library_file_names - libavutil.so.59 - libavcodec.so.61 - libavformat.so.61 - libavdevice.so.61 - libavfilter.so.10 - libswscale.so.8 - libswresample.so.5 - ) - set( - f8_library_file_names - libavutil.so.60 - libavcodec.so.62 - libavformat.so.62 - libavdevice.so.62 - libavfilter.so.11 - libswscale.so.9 - libswresample.so.6 - ) elseif (APPLE) - set(lib_dir "lib") set( platform_url ${base_url}/macos_arm64 @@ -124,60 +65,7 @@ elseif (APPLE) f8_sha256 beb936b76f25d2621228a12cdb67c9ae3d1eff7aa713ef8d1167ebf0c25bd5ec ) - - set( - f4_library_file_names - libavutil.56.dylib - libavcodec.58.dylib - libavformat.58.dylib - libavdevice.58.dylib - libavfilter.7.dylib - libswscale.5.dylib - libswresample.3.dylib - ) - set( - f5_library_file_names - libavutil.57.dylib - libavcodec.59.dylib - libavformat.59.dylib - libavdevice.59.dylib - libavfilter.8.dylib - libswscale.6.dylib - libswresample.4.dylib - ) - set( - f6_library_file_names - libavutil.58.dylib - libavcodec.60.dylib - libavformat.60.dylib - libavdevice.60.dylib - libavfilter.9.dylib - libswscale.7.dylib - libswresample.4.dylib - ) - set( - f7_library_file_names - libavutil.59.dylib - libavcodec.61.dylib - libavformat.61.dylib - libavdevice.61.dylib - libavfilter.10.dylib - libswscale.8.dylib - libswresample.5.dylib - ) - set( - f8_library_file_names - libavutil.60.dylib - libavcodec.62.dylib - libavformat.62.dylib - libavdevice.62.dylib - libavfilter.11.dylib - libswscale.9.dylib - libswresample.6.dylib - ) - elseif (WIN32) - set(lib_dir "bin") set( platform_url ${base_url}/windows_x86_64 @@ -202,57 +90,6 @@ elseif (WIN32) f8_sha256 bac845ac79876b104959cb0e7b9dec772a261116344dd17d2f97e7ddfac4a73f ) - - set( - f4_library_file_names - avutil.lib - avcodec.lib - avformat.lib - avdevice.lib - avfilter.lib - swscale.lib - swresample.lib - ) - set( - f5_library_file_names - avutil.lib - avcodec.lib - avformat.lib - avdevice.lib - avfilter.lib - swscale.lib - swresample.lib - ) - set( - f6_library_file_names - avutil.lib - avcodec.lib - avformat.lib - avdevice.lib - avfilter.lib - swscale.lib - swresample.lib - ) - set( - f7_library_file_names - avutil.lib - avcodec.lib - avformat.lib - avdevice.lib - avfilter.lib - swscale.lib - swresample.lib - ) - set( - f8_library_file_names - avutil.lib - avcodec.lib - avformat.lib - avdevice.lib - avfilter.lib - swscale.lib - swresample.lib - ) else() message( FATAL_ERROR @@ -293,68 +130,12 @@ FetchContent_Declare( FetchContent_MakeAvailable(f4 f5 f6 f7 f8) -add_library(ffmpeg4 INTERFACE) -add_library(ffmpeg5 INTERFACE) -add_library(ffmpeg6 INTERFACE) -add_library(ffmpeg7 INTERFACE) -add_library(ffmpeg8 INTERFACE) +# makes add_ffmpeg_target available +include("${CMAKE_CURRENT_SOURCE_DIR}/../share/cmake/TorchCodec/ffmpeg_versions.cmake") # Note: the f?_SOURCE_DIR variables were set by FetchContent_MakeAvailable -target_include_directories(ffmpeg4 INTERFACE ${f4_SOURCE_DIR}/include) -target_include_directories(ffmpeg5 INTERFACE ${f5_SOURCE_DIR}/include) -target_include_directories(ffmpeg6 INTERFACE ${f6_SOURCE_DIR}/include) -target_include_directories(ffmpeg7 INTERFACE ${f7_SOURCE_DIR}/include) -target_include_directories(ffmpeg8 INTERFACE ${f8_SOURCE_DIR}/include) - - -list( - TRANSFORM f4_library_file_names - PREPEND ${f4_SOURCE_DIR}/${lib_dir}/ - OUTPUT_VARIABLE f4_library_paths -) -list( - TRANSFORM f5_library_file_names - PREPEND ${f5_SOURCE_DIR}/${lib_dir}/ - OUTPUT_VARIABLE f5_library_paths -) -list( - TRANSFORM f6_library_file_names - PREPEND ${f6_SOURCE_DIR}/${lib_dir}/ - OUTPUT_VARIABLE f6_library_paths -) -list( - TRANSFORM f7_library_file_names - PREPEND ${f7_SOURCE_DIR}/${lib_dir}/ - OUTPUT_VARIABLE f7_library_paths -) -list( - TRANSFORM f8_library_file_names - PREPEND ${f8_SOURCE_DIR}/${lib_dir}/ - OUTPUT_VARIABLE f8_library_paths -) - -target_link_libraries( - ffmpeg4 - INTERFACE - ${f4_library_paths} -) -target_link_libraries( - ffmpeg5 - INTERFACE - ${f5_library_paths} -) -target_link_libraries( - ffmpeg6 - INTERFACE - ${f6_library_paths} -) -target_link_libraries( - ffmpeg7 - INTERFACE - ${f7_library_paths} -) -target_link_libraries( - ffmpeg8 - INTERFACE - ${f8_library_paths} -) +add_ffmpeg_target(4 "${f4_SOURCE_DIR}") +add_ffmpeg_target(5 "${f5_SOURCE_DIR}") +add_ffmpeg_target(6 "${f6_SOURCE_DIR}") +add_ffmpeg_target(7 "${f7_SOURCE_DIR}") +add_ffmpeg_target(8 "${f8_SOURCE_DIR}") diff --git a/src/torchcodec/_core/ops.py b/src/torchcodec/_core/ops.py index 32995c964..2ab9a017f 100644 --- a/src/torchcodec/_core/ops.py +++ b/src/torchcodec/_core/ops.py @@ -43,11 +43,12 @@ def load_torchcodec_shared_libraries(): exceptions = [] for ffmpeg_major_version in (8, 7, 6, 5, 4): pybind_ops_module_name = _get_pybind_ops_module_name(ffmpeg_major_version) - decoder_library_name = f"libtorchcodec_core{ffmpeg_major_version}" + core_library_name = f"libtorchcodec_core{ffmpeg_major_version}" custom_ops_library_name = f"libtorchcodec_custom_ops{ffmpeg_major_version}" pybind_ops_library_name = f"libtorchcodec_pybind_ops{ffmpeg_major_version}" try: - torch.ops.load_library(_get_extension_path(decoder_library_name)) + core_library_path = _get_extension_path(core_library_name) + torch.ops.load_library(core_library_path) torch.ops.load_library(_get_extension_path(custom_ops_library_name)) pybind_ops_library_path = _get_extension_path(pybind_ops_library_name) @@ -55,7 +56,7 @@ def load_torchcodec_shared_libraries(): _pybind_ops = _load_pybind11_module( pybind_ops_module_name, pybind_ops_library_path ) - return + return ffmpeg_major_version, core_library_path except Exception as e: # TODO: recording and reporting exceptions this way is OK for now as it's just for debugging, # but we should probably handle that via a proper logging mechanism. @@ -81,7 +82,7 @@ def load_torchcodec_shared_libraries(): ) -load_torchcodec_shared_libraries() +ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() # Note: We use disallow_in_graph because PyTorch does constant propagation of diff --git a/src/torchcodec/share/cmake/TorchCodec/TorchCodecConfig.cmake b/src/torchcodec/share/cmake/TorchCodec/TorchCodecConfig.cmake new file mode 100644 index 000000000..e199faa69 --- /dev/null +++ b/src/torchcodec/share/cmake/TorchCodec/TorchCodecConfig.cmake @@ -0,0 +1,76 @@ +# FindTorchCodec +# -------------- +# +# Finds the TorchCodec library +# +# This will define the following variables: +# +# TORCHCODEC_FOUND: True if the system has the TorchCodec library +# TORCHCODEC_VARIANTS: list of TorchCodec variants. A variant is a supported +# FFmpeg major version. +# +# and the following imported targets: +# +# torchcodec::ffmpeg${N} +# torchcodec::core${N} +# +# where N is a TorchCodec variant (FFmpeg major version) from +# TORCHCODEC_VARIANTS list. + +include(FindPackageHandleStandardArgs) +include("${CMAKE_CURRENT_LIST_DIR}/ffmpeg_versions.cmake") + +# Assume we are in /share/cmake/TorchCodec/TorchCodecConfig.cmake +get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(TORCHCODEC_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +# Include directories. +set(TORCHCODEC_INCLUDE_DIRS ${TORCHCODEC_INSTALL_PREFIX}/_core) +set(TORCHCODEC_VARIANTS "") + +function(add_torchcodec_target ffmpeg_major_version) + set(target torchcodec::core${ffmpeg_major_version}) + + if (NOT TARGET torchcodec::ffmpeg${ffmpeg_major_version}) + message(FATAL_ERROR "torchcodec::ffmpeg${ffmpeg_major_version} target is not defined") + endif() + + find_library(lib_path torchcodec_core${ffmpeg_major_version} + PATHS "${TORCHCODEC_INSTALL_PREFIX}" NO_CACHE NO_DEFAULT_PATH) + if (NOT lib_path) + message(FATAL_ERROR "torchcodec_core${ffmpeg_major_version} shared library is missing") + endif() + + message("Adding ${target} target") + add_library(${target} SHARED IMPORTED) + add_dependencies(${target} torchcodec::ffmpeg${ffmpeg_major_version}) + set_target_properties(${target} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${TORCHCODEC_INCLUDE_DIRS} + IMPORTED_LOCATION ${lib_path} + ) + + list(APPEND TORCHCODEC_VARIANTS "${ffmpeg_major_version}") + set(TORCHCODEC_VARIANTS "${TORCHCODEC_VARIANTS}" PARENT_SCOPE) +endfunction() + +# If any of the TORCHCODEC_FFMPEG${N}_INSTALL_PREFIX environment variables +# are defined, use them to locate the corresponding FFmpeg and TorchCodec targets. +# Otherwise, fall back to pkg-config to find FFmpeg. +set(use_pkg_config TRUE) +foreach(ffmpeg_major_version IN LISTS TORCHCODEC_SUPPORTED_FFMPEG_VERSIONS) + if (DEFINED ENV{TORCHCODEC_FFMPEG${ffmpeg_major_version}_INSTALL_PREFIX}) + add_ffmpeg_target( + "${ffmpeg_major_version}" + "$ENV{TORCHCODEC_FFMPEG${ffmpeg_major_version}_INSTALL_PREFIX}" + ) + add_torchcodec_target(${ffmpeg_major_version}) + set(use_pkg_config FALSE) + endif() +endforeach() + +if (use_pkg_config) + add_ffmpeg_target_with_pkg_config(ffmpeg_major_version) + add_torchcodec_target(${ffmpeg_major_version}) +endif() + +find_package_handle_standard_args(TorchCodec DEFAULT_MSG TORCHCODEC_VARIANTS) diff --git a/src/torchcodec/share/cmake/TorchCodec/ffmpeg_versions.cmake b/src/torchcodec/share/cmake/TorchCodec/ffmpeg_versions.cmake new file mode 100644 index 000000000..5f4ea87c9 --- /dev/null +++ b/src/torchcodec/share/cmake/TorchCodec/ffmpeg_versions.cmake @@ -0,0 +1,122 @@ +# This file exposes helpers to create and expose FFmpeg targets as torchcodec::ffmpeg${N} +# where N is the FFmpeg major version. + +# List of FFmpeg versions that TorchCodec can support - that's not a list of +# FFmpeg versions available on the current system! +set(TORCHCODEC_SUPPORTED_FFMPEG_VERSIONS "4;5;6;7;8") + +# Create and expose torchcodec::ffmpeg${ffmpeg_major_version} target which can +# then be used as a dependency in other targets. +# prefix is the path to the FFmpeg installation containing the usual `include` +# and `lib` directories. +function(add_ffmpeg_target ffmpeg_major_version prefix) + # Check that given ffmpeg major version is something we support and error out if + # it's not. + list(FIND TORCHCODEC_SUPPORTED_FFMPEG_VERSIONS "${ffmpeg_major_version}" _index) + if (_index LESS 0) + message(FATAL_ERROR "FFmpeg version ${ffmpeg_major_version} is not supported") + endif() + if (NOT DEFINED prefix) + message(FATAL_ERROR "No prefix defined calling add_ffmpeg_target()") + endif() + + # Define library names based on platform and FFmpeg version + if (LINUX) + if (ffmpeg_major_version EQUAL 4) + set(library_file_names libavutil.so.56 libavcodec.so.58 libavformat.so.58 libavdevice.so.58 libavfilter.so.7 libswscale.so.5 libswresample.so.3) + elseif (ffmpeg_major_version EQUAL 5) + set(library_file_names libavutil.so.57 libavcodec.so.59 libavformat.so.59 libavdevice.so.59 libavfilter.so.8 libswscale.so.6 libswresample.so.4) + elseif (ffmpeg_major_version EQUAL 6) + set(library_file_names libavutil.so.58 libavcodec.so.60 libavformat.so.60 libavdevice.so.60 libavfilter.so.9 libswscale.so.7 libswresample.so.4) + elseif (ffmpeg_major_version EQUAL 7) + set(library_file_names libavutil.so.59 libavcodec.so.61 libavformat.so.61 libavdevice.so.61 libavfilter.so.10 libswscale.so.8 libswresample.so.5) + elseif (ffmpeg_major_version EQUAL 8) + set(library_file_names libavutil.so.60 libavcodec.so.62 libavformat.so.62 libavdevice.so.62 libavfilter.so.11 libswscale.so.9 libswresample.so.6) + endif() + elseif (APPLE) + if (ffmpeg_major_version EQUAL 4) + set(library_file_names libavutil.56.dylib libavcodec.58.dylib libavformat.58.dylib libavdevice.58.dylib libavfilter.7.dylib libswscale.5.dylib libswresample.3.dylib) + elseif (ffmpeg_major_version EQUAL 5) + set(library_file_names libavutil.57.dylib libavcodec.59.dylib libavformat.59.dylib libavdevice.59.dylib libavfilter.8.dylib libswscale.6.dylib libswresample.4.dylib) + elseif (ffmpeg_major_version EQUAL 6) + set(library_file_names libavutil.58.dylib libavcodec.60.dylib libavformat.60.dylib libavdevice.60.dylib libavfilter.9.dylib libswscale.7.dylib libswresample.4.dylib) + elseif (ffmpeg_major_version EQUAL 7) + set(library_file_names libavutil.59.dylib libavcodec.61.dylib libavformat.61.dylib libavdevice.61.dylib libavfilter.10.dylib libswscale.8.dylib libswresample.5.dylib) + elseif (ffmpeg_major_version EQUAL 8) + set(library_file_names libavutil.60.dylib libavcodec.62.dylib libavformat.62.dylib libavdevice.62.dylib libavfilter.11.dylib libswscale.9.dylib libswresample.6.dylib) + endif() + elseif (WIN32) + set(library_file_names avutil.lib avcodec.lib avformat.lib avdevice.lib avfilter.lib swscale.lib swresample.lib) + else() + message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}") + endif() + + set(target "torchcodec::ffmpeg${ffmpeg_major_version}") + set(include_dir "${prefix}/include") + if (LINUX OR APPLE) + set(lib_dir "${prefix}/lib") + elseif (WIN32) + set(lib_dir "${prefix}/bin") + else() + message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}") + endif() + + list( + TRANSFORM library_file_names + PREPEND ${lib_dir}/ + OUTPUT_VARIABLE lib_paths + ) + + message("Adding ${target} target") + # Verify that ffmpeg includes and libraries actually exist. + foreach (path IN LISTS include_dir lib_paths) + if (NOT EXISTS "${path}") + message(FATAL_ERROR "${path} does not exist") + endif() + endforeach() + + # Actually define the target + add_library(${target} INTERFACE IMPORTED) + target_include_directories(${target} INTERFACE ${include_dir}) + target_link_libraries(${target} INTERFACE ${lib_paths}) +endfunction() + +# Create and expose torchcodec::ffmpeg${ffmpeg_major_version} target which can +# then be used as a dependency in other targets. +# The FFmpeg installation is found by pkg-config. +function(add_ffmpeg_target_with_pkg_config ret_ffmpeg_major_version_var) + find_package(PkgConfig REQUIRED) + pkg_check_modules(TORCHCODEC_LIBAV REQUIRED IMPORTED_TARGET + libavdevice + libavfilter + libavformat + libavcodec + libavutil + libswresample + libswscale + ) + + # Split libavcodec's version string by '.' and convert it to a list + # The TORCHCODEC_LIBAV_libavcodec_VERSION is made available by pkg-config. + string(REPLACE "." ";" libavcodec_version_list ${TORCHCODEC_LIBAV_libavcodec_VERSION}) + # Get the first element of the list, which is the major version + list(GET libavcodec_version_list 0 libavcodec_major_version) + + if (${libavcodec_major_version} STREQUAL "58") + set(ffmpeg_major_version "4") + elseif (${libavcodec_major_version} STREQUAL "59") + set(ffmpeg_major_version "5") + elseif (${libavcodec_major_version} STREQUAL "60") + set(ffmpeg_major_version "6") + elseif (${libavcodec_major_version} STREQUAL "61") + set(ffmpeg_major_version "7") + elseif (${libavcodec_major_version} STREQUAL "62") + set(ffmpeg_major_version "8") + else() + message(FATAL_ERROR "Unsupported libavcodec version: ${libavcodec_major_version}") + endif() + + message("Adding torchcodec::ffmpeg${ffmpeg_major_version} target") + add_library(torchcodec::ffmpeg${ffmpeg_major_version} ALIAS PkgConfig::TORCHCODEC_LIBAV) + set(${ret_ffmpeg_major_version_var} ${ffmpeg_major_version} PARENT_SCOPE) +endfunction()