diff --git a/.github/workflows/windows_wheel.yaml b/.github/workflows/windows_wheel.yaml index 38cc53be9..b594c54dc 100644 --- a/.github/workflows/windows_wheel.yaml +++ b/.github/workflows/windows_wheel.yaml @@ -71,8 +71,7 @@ jobs: # TODO: FFmpeg 5 on Windows segfaults in avcodec_open2() when passing # bad parameters. # See https://github.com/pytorch/torchcodec/pull/806 - # TODO: Support FFmpeg 8 on Windows - ffmpeg-version-for-tests: ['4.4.2', '6.1.1', '7.0.1'] + ffmpeg-version-for-tests: ['4.4.2', '6.1.1', '7.0.1', '8.0'] needs: build steps: - uses: actions/download-artifact@v4 @@ -83,7 +82,11 @@ jobs: uses: conda-incubator/setup-miniconda@v2 with: auto-update-conda: true - miniconda-version: "latest" + # Using miniforge instead of miniconda ensures that the default + # conda channel is conda-forge instead of main/default. This ensures + # ABI consistency between dependencies: + # https://conda-forge.org/docs/user/transitioning_from_defaults/ + miniforge-version: latest activate-environment: test python-version: ${{ matrix.python-version }} - name: Update pip diff --git a/test/test_encoders.py b/test/test_encoders.py index f8b5b3519..c5946654d 100644 --- a/test/test_encoders.py +++ b/test/test_encoders.py @@ -16,6 +16,7 @@ from .utils import ( assert_tensor_close_on_at_least, get_ffmpeg_major_version, + get_ffmpeg_minor_version, in_fbcode, IS_WINDOWS, NASA_AUDIO_MP3, @@ -23,6 +24,11 @@ TestContainerFile, ) +IS_WINDOWS_WITH_FFMPEG_LE_70 = IS_WINDOWS and ( + get_ffmpeg_major_version() < 7 + or (get_ffmpeg_major_version() == 7 and get_ffmpeg_minor_version() == 0) +) + @pytest.fixture def with_ffmpeg_debug_logs(): @@ -155,7 +161,11 @@ def test_bad_input_parametrized(self, method, tmp_path): avcodec_open2_failed_msg = "avcodec_open2 failed: Invalid argument" with pytest.raises( RuntimeError, - match=avcodec_open2_failed_msg if IS_WINDOWS else "invalid sample rate=10", + match=( + avcodec_open2_failed_msg + if IS_WINDOWS_WITH_FFMPEG_LE_70 + else "invalid sample rate=10" + ), ): getattr(decoder, method)(**valid_params) @@ -164,14 +174,18 @@ def test_bad_input_parametrized(self, method, tmp_path): ) with pytest.raises( RuntimeError, - match=avcodec_open2_failed_msg if IS_WINDOWS else "invalid sample rate=10", + match=( + avcodec_open2_failed_msg + if IS_WINDOWS_WITH_FFMPEG_LE_70 + else "invalid sample rate=10" + ), ): getattr(decoder, method)(sample_rate=10, **valid_params) with pytest.raises( RuntimeError, match=( avcodec_open2_failed_msg - if IS_WINDOWS + if IS_WINDOWS_WITH_FFMPEG_LE_70 else "invalid sample rate=99999999" ), ): @@ -192,7 +206,7 @@ def test_bad_input_parametrized(self, method, tmp_path): for num_channels in (0, 3): match = ( avcodec_open2_failed_msg - if IS_WINDOWS + if IS_WINDOWS_WITH_FFMPEG_LE_70 else re.escape( f"Desired number of channels ({num_channels}) is not supported" ) @@ -316,7 +330,7 @@ def test_against_cli( else: rtol, atol = None, None - if IS_WINDOWS and format == "mp3": + if IS_WINDOWS_WITH_FFMPEG_LE_70 and format == "mp3": # We're getting a "Could not open input file" on Windows mp3 files when decoding. # TODO: https://github.com/pytorch/torchcodec/issues/837 return @@ -370,7 +384,7 @@ def test_against_to_file( else: raise ValueError(f"Unknown method: {method}") - if not (IS_WINDOWS and format == "mp3"): + if not (IS_WINDOWS_WITH_FFMPEG_LE_70 and format == "mp3"): # We're getting a "Could not open input file" on Windows mp3 files when decoding. # TODO: https://github.com/pytorch/torchcodec/issues/837 torch.testing.assert_close( diff --git a/test/utils.py b/test/utils.py index 61bf06295..e11411bd2 100644 --- a/test/utils.py +++ b/test/utils.py @@ -76,16 +76,27 @@ def make_video_decoder(*args, **kwargs) -> tuple[VideoDecoder, str]: return dec, clean_device -def get_ffmpeg_major_version(): +def _get_ffmpeg_version_string(): ffmpeg_version = get_ffmpeg_library_versions()["ffmpeg_version"] # When building FFmpeg from source there can be a `n` prefix in the version # string. This is quite brittle as we're using av_version_info(), which has # no stable format. See https://github.com/pytorch/torchcodec/issues/100 if ffmpeg_version.startswith("n"): ffmpeg_version = ffmpeg_version.removeprefix("n") + + return ffmpeg_version + + +def get_ffmpeg_major_version(): + ffmpeg_version = _get_ffmpeg_version_string() return int(ffmpeg_version.split(".")[0]) +def get_ffmpeg_minor_version(): + ffmpeg_version = _get_ffmpeg_version_string() + return int(ffmpeg_version.split(".")[1]) + + def cuda_version_used_for_building_torch() -> Optional[tuple[int, int]]: # Return the CUDA version that was used to build PyTorch. That's not always # the same as the CUDA version that is currently installed on the running