-
Notifications
You must be signed in to change notification settings - Fork 77
Find default hardware encoder in VideoEncoder #1124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b2bf92d
45efb9f
84fc4fb
217c490
1c19b1c
d3e1e32
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -885,7 +885,6 @@ def encode_to_tensor(frames): | |
| common_params = dict( | ||
| crf=0, | ||
| pixel_format="yuv444p" if device == "cpu" else None, | ||
| codec="h264_nvenc" if device != "cpu" else None, | ||
| ) | ||
| if method == "to_file": | ||
| dest = str(tmp_path / "output.mp4") | ||
|
|
@@ -1337,28 +1336,28 @@ def test_extra_options_utilized(self, tmp_path, profile, colorspace, color_range | |
|
|
||
| @needs_ffmpeg_cli | ||
| @pytest.mark.needs_cuda | ||
| # TODO-VideoEncoder: Auto-select codec for GPU encoding | ||
| @pytest.mark.parametrize("method", ("to_file", "to_tensor", "to_file_like")) | ||
| # TODO-VideoEncoder: Enable additional pixel formats ("yuv420p", "yuv444p") | ||
| @pytest.mark.parametrize( | ||
| "format_codec", | ||
| ("format", "codec"), | ||
| [ | ||
| ("mov", None), # will default to h264_nvenc | ||
| ("mov", "h264_nvenc"), | ||
| ("mp4", "hevc_nvenc"), | ||
| ("avi", "h264_nvenc"), | ||
| ("mp4", "hevc_nvenc"), # use non-default codec | ||
| pytest.param( | ||
| ("mkv", "av1_nvenc"), | ||
| "mkv", | ||
| "av1_nvenc", | ||
| marks=pytest.mark.skipif( | ||
| IN_GITHUB_CI, reason="av1_nvenc is not supported on CI" | ||
| ), | ||
| ), | ||
| ], | ||
| ) | ||
| @pytest.mark.parametrize("method", ("to_file", "to_tensor", "to_file_like")) | ||
| # TODO-VideoEncoder: Enable additional pixel formats ("yuv420p", "yuv444p") | ||
| def test_nvenc_against_ffmpeg_cli(self, tmp_path, format_codec, method): | ||
| def test_nvenc_against_ffmpeg_cli(self, tmp_path, method, format, codec): | ||
| # Encode with FFmpeg CLI using nvenc codecs | ||
| format, codec = format_codec | ||
| device = "cuda" | ||
| qp = 1 # Lossless (qp=0) is not supported on av1_nvenc, so we use 1 | ||
| qp = 1 # Use near lossless encoding to reduce noise and support av1_nvenc | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. QQ would we be able to assert closer expected results (stricter tolerance) if we set qp = 0 for the other codecs? If we can, then it might be worth it
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, at |
||
| source_frames = self.decode(TEST_SRC_2_720P.path).data.to(device) | ||
|
|
||
| temp_raw_path = str(tmp_path / "temp_input.raw") | ||
|
|
@@ -1381,21 +1380,18 @@ def test_nvenc_against_ffmpeg_cli(self, tmp_path, format_codec, method): | |
| str(frame_rate), | ||
| "-i", | ||
| temp_raw_path, | ||
| "-c:v", | ||
| codec, # Use specified NVENC hardware encoder | ||
| ] | ||
| # CLI requires explicit codec for nvenc | ||
| ffmpeg_cmd.extend(["-c:v", codec if codec is not None else "h264_nvenc"]) | ||
| # VideoEncoder will select an NVENC encoder by default since the frames are on GPU. | ||
|
|
||
| ffmpeg_cmd.extend(["-pix_fmt", "nv12"]) # Output format is always NV12 | ||
| if codec == "av1_nvenc": | ||
| ffmpeg_cmd.extend(["-rc", "constqp"]) # Set rate control mode for AV1 | ||
| ffmpeg_cmd.extend(["-qp", str(qp)]) # Use lossless qp for other codecs | ||
| ffmpeg_cmd.extend(["-qp", str(qp)]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes this is intentional, I realized |
||
| ffmpeg_cmd.extend([ffmpeg_encoded_path]) | ||
| subprocess.run(ffmpeg_cmd, check=True, capture_output=True) | ||
| encoder = VideoEncoder(frames=source_frames, frame_rate=frame_rate) | ||
|
|
||
| encoder = VideoEncoder(frames=source_frames, frame_rate=frame_rate) | ||
| encoder_extra_options = {"qp": qp} | ||
| if codec == "av1_nvenc": | ||
| encoder_extra_options["rc"] = 0 # constqp mode | ||
| if method == "to_file": | ||
| encoder_output_path = str(tmp_path / f"nvenc_output.{format}") | ||
| encoder.to_file( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.