Skip to content

Commit

Permalink
* Adding QP mode for FFmpeg Nvenc encoding
Browse files Browse the repository at this point in the history
* Adding more preview positions
* Adding ultra high quality mode for ffmpeg nvenc encoder
* Fixing #631 VVC Level can't be set to 0 anymore (thanks to GT500org)
  • Loading branch information
cdgriffith committed Feb 21, 2025
1 parent 4944950 commit 9359a79
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 12 deletions.
7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Version 5.9.0

* Adding QP mode for FFmpeg Nvenc encoding
* Adding more preview positions
* Adding ultra high quality mode for ffmpeg nvenc encoder
* Fixing #631 VVC Level can't be set to 0 anymore (thanks to GT500org)

## Version 5.8.2

* Fixing #610 Do not try to divide by zero if HDR metadata has bad values (thanks to Noelle Leigh)
Expand Down
14 changes: 14 additions & 0 deletions fastflix/encoders/common/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ def generate_ffmpeg_start(
)


def rigaya_data(streams, copy_data=False, **_):
if not copy_data:
return ""
datas = []
for stream in streams:
if stream["codec_type"] == "data":
datas.append(str(stream["index"]))
if not datas:
return ""
return f"--data-copy {','.join(datas)}"


def generate_ending(
audio,
subtitles,
Expand All @@ -109,13 +121,15 @@ def generate_ending(
null_ending=False,
output_fps: Union[str, None] = None,
disable_rotate_metadata=False,
copy_data=False,
**_,
):
ending = (
f" {'-map_metadata -1' if remove_metadata else '-map_metadata 0'} "
f"{'-map_chapters 0' if copy_chapters else '-map_chapters -1'} "
f"{f'-r {output_fps}' if output_fps else ''} "
f"{audio} {subtitles} {cover} "
f"{'-map 0:d -c:d copy ' if copy_data else ''}"
)

# In case they use a mp4 container, nix the rotation
Expand Down
4 changes: 4 additions & 0 deletions fastflix/encoders/ffmpeg_hevc_nvenc/command_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def build(fastflix: FastFlix):
if settings.level:
beginning += f"-level:v {settings.level} "

if not settings.bitrate:
command = (f"{beginning} -qp:v {settings.qp} -preset:v {settings.preset} " f"{settings.extra}") + ending
return [Command(command=command, name="Single QP encode", exe="ffmpeg")]

pass_log_file = fastflix.current_video.work_path / f"pass_log_file_{secrets.token_hex(10)}"

command_1 = (
Expand Down
7 changes: 3 additions & 4 deletions fastflix/encoders/ffmpeg_hevc_nvenc/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ def init_tune(self):
return self._add_combo_box(
label="Tune",
widget_name="tune",
tooltip="Tune the settings for a particular type of source or situation\nhq - High Quality, ll - Low Latency, ull - Ultra Low Latency",
options=["hq", "ll", "ull", "lossless"],
tooltip="Tune the settings for a particular type of source or situation\nhq - High Quality, uqh - Ultra High Quality, ll - Low Latency, ull - Ultra Low Latency",
options=["hq", "uhq", "ll", "ull", "lossless"],
opt="tune",
)

Expand Down Expand Up @@ -248,10 +248,9 @@ def init_b_ref_mode(self):
return layout

def init_modes(self):
layout = self._add_modes(recommended_bitrates, recommended_crfs, qp_name="qp", add_qp=False)
layout = self._add_modes(recommended_bitrates, recommended_crfs, qp_name="qp")
self.qp_radio.setChecked(False)
self.bitrate_radio.setChecked(True)
self.qp_radio.setDisabled(True)
return layout

def mode_update(self):
Expand Down
8 changes: 6 additions & 2 deletions fastflix/encoders/vvc/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ def init_tier(self):
)

def init_levels(self):
# https://github.com/fraunhoferhhi/vvenc/blob/cf8ba5ed74f8e8c7c9e7b6f81f7fb08bce6241b0/source/Lib/vvenc/vvencCfg.cpp#L159
return self._add_combo_box(
label="IDC Level",
tooltip="Set the IDC level",
widget_name="levelidc",
options=[
"0",
t("auto"),
"1",
"2",
"2.1",
Expand All @@ -135,6 +136,7 @@ def init_levels(self):
"6.1",
"6.2",
"6.3",
"15.5",
],
opt="levelidc",
)
Expand Down Expand Up @@ -226,12 +228,14 @@ def update_video_encoder_settings(self):

vvc_params_text = self.widgets.vvc_params.text().strip()

level = self.widgets.levelidc.currentText() if self.widgets.levelidc.currentIndex() > 0 else None

settings = VVCSettings(
preset=self.widgets.preset.currentText(),
max_muxing_queue_size=self.widgets.max_mux.currentText(),
pix_fmt=self.widgets.pix_fmt.currentText().split(":")[1].strip(),
tier=self.widgets.tier.currentText(),
levelidc=self.widgets.levelidc.currentText(),
levelidc=level,
vvc_params=vvc_params_text.split(":") if vvc_params_text else [],
extra=self.ffmpeg_extras,
extra_both_passes=self.widgets.extra_both_passes.isChecked(),
Expand Down
5 changes: 4 additions & 1 deletion fastflix/flix.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ def ffprobe_configuration(app, config: Config, **_):


def probe(app: FastFlixApp, file: Path) -> Box:
"""Run FFprobe on a file"""
"""
Run FFprobe on a file
ffprobe -v quiet -loglevel panic -print_format json -show_format -show_streams
"""
command = [
f"{app.fastflix.config.ffprobe}",
"-v",
Expand Down
1 change: 1 addition & 0 deletions fastflix/models/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class VideoSettings(BaseModel):
brightness: Optional[str] = None
contrast: Optional[str] = None
saturation: Optional[str] = None
copy_data: bool = False
video_encoder_settings: Optional[
Union[
x265Settings,
Expand Down
2 changes: 1 addition & 1 deletion fastflix/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__version__ = "5.8.2"
__version__ = "5.9.0"
__author__ = "Chris Griffith"
23 changes: 19 additions & 4 deletions fastflix/widgets/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class MainWidgets(BaseModel):
output_type_combo: QtWidgets.QComboBox = Field(default_factory=QtWidgets.QComboBox)
output_directory_select: QtWidgets.QPushButton = None
model_config = ConfigDict(arbitrary_types_allowed=True)
copy_data: QtWidgets.QCheckBox = None

def items(self):
for key in dir(self):
Expand Down Expand Up @@ -394,8 +395,8 @@ def init_thumb_time_selector(self):

self.widgets.thumb_time = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.widgets.thumb_time.setMinimum(1)
self.widgets.thumb_time.setMaximum(10)
self.widgets.thumb_time.setValue(2)
self.widgets.thumb_time.setMaximum(100)
self.widgets.thumb_time.setValue(25)
self.widgets.thumb_time.setTickPosition(QtWidgets.QSlider.TicksBelow)
self.widgets.thumb_time.setTickInterval(1)
self.widgets.thumb_time.setAutoFillBackground(False)
Expand Down Expand Up @@ -572,8 +573,21 @@ def init_checkboxes(self):
extra_details_layout = QtWidgets.QVBoxLayout()
extra_details_layout.addWidget(self.widgets.deinterlace)
extra_details_layout.addWidget(self.widgets.remove_hdr)

transform_layout.addLayout(extra_details_layout)

# another_layout = QtWidgets.QVBoxLayout()
#
# self.widgets.copy_data = QtWidgets.QCheckBox(t("Copy Data"))
# self.widgets.copy_data.setChecked(False)
# self.widgets.copy_data.toggled.connect(self.page_update)
# self.widgets.copy_data.setToolTip(
# f'{t("Copy all data streams from the source file.")}'
# )
#
# another_layout.addWidget(self.widgets.copy_data)
# another_layout.addWidget(QtWidgets.QWidget())
# transform_layout.addLayout(another_layout)

return transform_layout

def init_video_track_select(self):
Expand Down Expand Up @@ -1624,7 +1638,7 @@ def remove_hdr(self) -> bool:

@property
def preview_place(self) -> Union[float, int]:
ticks = self.app.fastflix.current_video.duration / 10
ticks = self.app.fastflix.current_video.duration / 100
return (self.widgets.thumb_time.value() - 1) * ticks

@reusables.log_exception("fastflix", show_traceback=False)
Expand Down Expand Up @@ -1739,6 +1753,7 @@ def get_all_settings(self):
video_title=self.video_options.advanced.video_title.text(),
video_track_title=self.video_options.advanced.video_track_title.text(),
remove_hdr=self.remove_hdr,
copy_data=self.widgets.copy_data.isChecked(),
)

self.video_options.get_settings()
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies = [
"python-box[all]>=6.0,<7.0",
"requests>=2.28,<3.0",
"reusables>=0.9.6,<0.10.0",
"setuptools>=75.8",
]

[project.optional-dependencies]
Expand Down

0 comments on commit 9359a79

Please sign in to comment.