Send resolution / fps data in job submission

This commit is contained in:
Brett Williams
2026-01-06 19:33:46 -06:00
parent 2fdabd3a9d
commit e7cecf6009
4 changed files with 135 additions and 24 deletions

View File

@@ -40,10 +40,16 @@ class BlenderRenderWorker(BaseRenderWorker):
cmd.append('--python-expr') cmd.append('--python-expr')
python_exp = 'import bpy; bpy.context.scene.render.use_overwrite = False;' python_exp = 'import bpy; bpy.context.scene.render.use_overwrite = False;'
# Setup Custom Resolution
if self.args.get('resolution'):
res = self.args.get('resolution')
python_exp += 'bpy.context.scene.render.resolution_percentage = 100;'
python_exp += f'bpy.context.scene.render.resolution_x={res[0]}; bpy.context.scene.render.resolution_y={res[1]};'
# Setup Custom Camera # Setup Custom Camera
custom_camera = self.args.get('camera', None) custom_camera = self.args.get('camera', None)
if custom_camera: if custom_camera:
python_exp = python_exp + f"bpy.context.scene.camera = bpy.data.objects['{custom_camera}'];" python_exp += f"bpy.context.scene.camera = bpy.data.objects['{custom_camera}'];"
# Set Render Device for Cycles (gpu/cpu/any) # Set Render Device for Cycles (gpu/cpu/any)
if blender_engine == 'CYCLES': if blender_engine == 'CYCLES':

View File

@@ -19,8 +19,8 @@ class FFMPEGRenderWorker(BaseRenderWorker):
cmd = [self.engine_path, '-y', '-stats', '-i', self.input_path] cmd = [self.engine_path, '-y', '-stats', '-i', self.input_path]
# Resize frame # Resize frame
if self.args.get('x_resolution', None) and self.args.get('y_resolution', None): if self.args.get('resolution', None):
cmd.extend(['-vf', f"scale={self.args['x_resolution']}:{self.args['y_resolution']}"]) cmd.extend(['-vf', f"scale={self.args['resolution'][0]}:{self.args['resolution'][1]}"])
# Convert raw args from string if available # Convert raw args from string if available
raw_args = self.args.get('raw', None) raw_args = self.args.get('raw', None)

View File

@@ -13,17 +13,21 @@ from src.api.server_proxy import RenderServerProxy
from src.engines.engine_manager import EngineManager from src.engines.engine_manager import EngineManager
from src.ui.engine_help_window import EngineHelpViewer from src.ui.engine_help_window import EngineHelpViewer
from src.utilities.zeroconf_server import ZeroconfServer from src.utilities.zeroconf_server import ZeroconfServer
from src.utilities.misc_helper import COMMON_RESOLUTIONS
from utilities.misc_helper import COMMON_FRAME_RATES
class NewRenderJobForm(QWidget): class NewRenderJobForm(QWidget):
def __init__(self, project_path=None): def __init__(self, project_path=None):
super().__init__() super().__init__()
self.notes_group = None self.resolution_options_list = None
self.frame_rate_input = None
self.resolution_x_input = None self.resolution_x_input = None
self.engine_group = None
self.output_settings_group = None
self.resolution_y_input = None self.resolution_y_input = None
self.fps_options_list = None
self.fps_input = None
self.engine_group = None
self.notes_group = None
self.output_settings_group = None
self.project_path = project_path self.project_path = project_path
# UI # UI
@@ -174,34 +178,64 @@ class NewRenderJobForm(QWidget):
frame_range_layout.addWidget(QLabel("Frames:")) frame_range_layout.addWidget(QLabel("Frames:"))
self.start_frame_input = QSpinBox() self.start_frame_input = QSpinBox()
self.start_frame_input.setRange(1, 99999) self.start_frame_input.setRange(1, 99999)
self.start_frame_input.setFixedWidth(80)
self.end_frame_input = QSpinBox() self.end_frame_input = QSpinBox()
self.end_frame_input.setRange(1, 99999) self.end_frame_input.setRange(1, 99999)
self.start_frame_input.setFixedWidth(80)
frame_range_layout.addWidget(self.start_frame_input) frame_range_layout.addWidget(self.start_frame_input)
frame_range_layout.addWidget(QLabel("to")) frame_range_layout.addWidget(QLabel("to"))
frame_range_layout.addWidget(self.end_frame_input) frame_range_layout.addWidget(self.end_frame_input)
frame_range_layout.addStretch()
output_settings_layout.addLayout(frame_range_layout) output_settings_layout.addLayout(frame_range_layout)
# Resolution & FPS # --- Resolution & FPS Group ---
resolution_layout = QHBoxLayout() resolution_group = QGroupBox("Resolution / Frame Rate")
resolution_layout.addWidget(QLabel("Resolution:")) output_settings_layout.addWidget(resolution_group)
resolution_group_layout = QVBoxLayout()
resolution_group.setLayout(resolution_group_layout)
# Resolution
resolution_layout = QHBoxLayout(resolution_group)
self.resolution_options_list = QComboBox()
self.resolution_options_list.setFixedWidth(200)
self.resolution_options_list.addItem("Original Size")
for res in COMMON_RESOLUTIONS:
self.resolution_options_list.addItem(res)
self.resolution_options_list.currentIndexChanged.connect(self._resolution_preset_changed)
resolution_layout.addWidget(self.resolution_options_list)
resolution_group_layout.addLayout(resolution_layout)
self.resolution_x_input = QSpinBox() self.resolution_x_input = QSpinBox()
self.resolution_x_input.setRange(1, 9999) self.resolution_x_input.setRange(1, 9999)
self.resolution_x_input.setValue(1920) self.resolution_x_input.setValue(1920)
self.resolution_x_input.setFixedWidth(80)
resolution_layout.addWidget(self.resolution_x_input)
self.resolution_y_input = QSpinBox() self.resolution_y_input = QSpinBox()
self.resolution_y_input.setRange(1, 9999) self.resolution_y_input.setRange(1, 9999)
self.resolution_y_input.setValue(1080) self.resolution_y_input.setValue(1080)
self.frame_rate_input = QDoubleSpinBox() self.resolution_y_input.setFixedWidth(80)
self.frame_rate_input.setDecimals(3)
self.frame_rate_input.setRange(1.0, 999.0)
self.frame_rate_input.setValue(23.976)
resolution_layout.addWidget(self.resolution_x_input)
resolution_layout.addWidget(QLabel("x")) resolution_layout.addWidget(QLabel("x"))
resolution_layout.addWidget(self.resolution_y_input) resolution_layout.addWidget(self.resolution_y_input)
resolution_layout.addWidget(QLabel("@")) resolution_layout.addStretch()
resolution_layout.addWidget(self.frame_rate_input)
resolution_layout.addWidget(QLabel("fps")) fps_layout = QHBoxLayout(resolution_group)
output_settings_layout.addLayout(resolution_layout) self.fps_options_list = QComboBox()
self.fps_options_list.setFixedWidth(200)
self.fps_options_list.addItem("Original FPS")
for fps_option in COMMON_FRAME_RATES:
self.fps_options_list.addItem(fps_option)
self.fps_options_list.currentIndexChanged.connect(self._fps_preset_changed)
fps_layout.addWidget(self.fps_options_list)
self.fps_input = QDoubleSpinBox()
self.fps_input.setDecimals(3)
self.fps_input.setRange(1.0, 999.0)
self.fps_input.setValue(23.976)
self.fps_input.setFixedWidth(80)
fps_layout.addWidget(self.fps_input)
fps_layout.addWidget(QLabel("fps"))
fps_layout.addStretch()
resolution_group_layout.addLayout(fps_layout)
output_settings_layout.addStretch() output_settings_layout.addStretch()
@@ -279,6 +313,22 @@ class NewRenderJobForm(QWidget):
self.toggle_engine_enablement(False) self.toggle_engine_enablement(False)
self.tabs.setCurrentIndex(0) self.tabs.setCurrentIndex(0)
def _resolution_preset_changed(self, index):
selected_res = COMMON_RESOLUTIONS.get(self.resolution_options_list.currentText())
if selected_res:
self.resolution_x_input.setValue(selected_res[0])
self.resolution_y_input.setValue(selected_res[1])
elif index == 0:
self.resolution_x_input.setValue(self.project_info.get('resolution_x'))
self.resolution_y_input.setValue(self.project_info.get('resolution_y'))
def _fps_preset_changed(self, index):
selected_fps = COMMON_FRAME_RATES.get(self.fps_options_list.currentText())
if selected_fps:
self.fps_input.setValue(selected_fps)
elif index == 0:
self.fps_input.setValue(self.project_info.get('fps'))
def update_engine_info(self): def update_engine_info(self):
# get the engine info and add them all to the ui # get the engine info and add them all to the ui
self.engine_info = self.server_proxy.get_engine_info(response_type='full') self.engine_info = self.server_proxy.get_engine_info(response_type='full')
@@ -363,7 +413,7 @@ class NewRenderJobForm(QWidget):
self.end_frame_input.setValue(self.project_info.get('frame_end')) self.end_frame_input.setValue(self.project_info.get('frame_end'))
self.resolution_x_input.setValue(self.project_info.get('resolution_x')) self.resolution_x_input.setValue(self.project_info.get('resolution_x'))
self.resolution_y_input.setValue(self.project_info.get('resolution_y')) self.resolution_y_input.setValue(self.project_info.get('resolution_y'))
self.frame_rate_input.setValue(self.project_info.get('fps')) self.fps_input.setValue(self.project_info.get('fps'))
# Cameras # Cameras
self.cameras_list.clear() self.cameras_list.clear()
@@ -387,8 +437,7 @@ class NewRenderJobForm(QWidget):
# Dynamic Engine Options # Dynamic Engine Options
clear_layout(self.engine_options_layout) # clear old options clear_layout(self.engine_options_layout) # clear old options
# dynamically populate option list # dynamically populate option list
system_info = self.engine_info.get(engine.name(), {}).get('system_info', {}) self.current_engine_options = engine().ui_options()
self.current_engine_options = engine.ui_options(system_info=system_info)
for option in self.current_engine_options: for option in self.current_engine_options:
h_layout = QHBoxLayout() h_layout = QHBoxLayout()
label = QLabel(option['name'].replace('_', ' ').capitalize() + ':') label = QLabel(option['name'].replace('_', ' ').capitalize() + ':')
@@ -488,11 +537,14 @@ class SubmitWorker(QThread):
try: try:
hostname = self.window.server_input.currentText() hostname = self.window.server_input.currentText()
resolution = (self.window.resolution_x_input.text(), self.window.resolution_y_input.text())
job_json = {'owner': psutil.Process().username() + '@' + socket.gethostname(), job_json = {'owner': psutil.Process().username() + '@' + socket.gethostname(),
'engine_name': self.window.engine_type.currentText().lower(), 'engine_name': self.window.engine_type.currentText().lower(),
'engine_version': self.window.engine_version_combo.currentText(), 'engine_version': self.window.engine_version_combo.currentText(),
'args': {'raw': self.window.raw_args.text(), 'args': {'raw': self.window.raw_args.text(),
'export_format': self.window.file_format_combo.currentText()}, 'export_format': self.window.file_format_combo.currentText(),
'resolution': resolution,
'fps': self.window.fps_input.text(),},
'output_path': self.window.job_name_input.text(), 'output_path': self.window.job_name_input.text(),
'start_frame': self.window.start_frame_input.value(), 'start_frame': self.window.start_frame_input.value(),
'end_frame': self.window.end_frame_input.value(), 'end_frame': self.window.end_frame_input.value(),

View File

@@ -370,3 +370,56 @@ def get_gpu_info():
return get_windows_gpu_info() return get_windows_gpu_info()
else: # Assume Linux or other else: # Assume Linux or other
return get_linux_gpu_info() return get_linux_gpu_info()
COMMON_RESOLUTIONS = {
# SD
"SD_480p": (640, 480),
"NTSC_DVD": (720, 480),
"PAL_DVD": (720, 576),
# HD
"HD_720p": (1280, 720),
"HD_900p": (1600, 900),
"HD_1080p": (1920, 1080),
# Cinema / Film
"2K_DCI": (2048, 1080),
"4K_DCI": (4096, 2160),
# UHD / Consumer
"UHD_4K": (3840, 2160),
"UHD_5K": (5120, 2880),
"UHD_8K": (7680, 4320),
# Ultrawide / Aspect Variants
"UW_1080p": (2560, 1080),
"UW_1440p": (3440, 1440),
"UW_5K": (5120, 2160),
# Mobile / Social
"VERTICAL_1080x1920": (1080, 1920),
"SQUARE_1080": (1080, 1080),
# Classic / Legacy
"VGA": (640, 480),
"SVGA": (800, 600),
"XGA": (1024, 768),
"WXGA": (1280, 800),
}
COMMON_FRAME_RATES = {
"23.976 (NTSC Film)": 23.976,
"24 (Cinema)": 24.0,
"25 (PAL)": 25.0,
"29.97 (NTSC)": 29.97,
"30": 30.0,
"48 (HFR Film)": 48.0,
"50 (PAL HFR)": 50.0,
"59.94": 59.94,
"60": 60.0,
"72": 72.0,
"90 (VR)": 90.0,
"120": 120.0,
"144 (Gaming)": 144.0,
"240 (HFR)": 240.0,
}