mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 00:44:52 +01:00
Merge remote-tracking branch 'origin/bugfix/multiselect_combobox_line_fix' into feature/redshift-proxy-support
This commit is contained in:
commit
597bd54f06
3 changed files with 17 additions and 450 deletions
|
|
@ -127,7 +127,7 @@ def filter_pyblish_plugins(plugins):
|
|||
plugin_kind = file.split(os.path.sep)[-2:-1][0]
|
||||
|
||||
# TODO: change after all plugins are moved one level up
|
||||
if host_from_file == "pype":
|
||||
if host_from_file == "openpype":
|
||||
host_from_file = "global"
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -2,12 +2,18 @@ import os
|
|||
import re
|
||||
import copy
|
||||
import json
|
||||
import pyblish.api
|
||||
|
||||
import clique
|
||||
|
||||
import pyblish.api
|
||||
import openpype.api
|
||||
import openpype.lib
|
||||
from openpype.lib import should_decompress, \
|
||||
get_decompress_dir, decompress
|
||||
from openpype.lib import (
|
||||
get_ffmpeg_tool_path,
|
||||
ffprobe_streams,
|
||||
should_decompress,
|
||||
get_decompress_dir,
|
||||
decompress
|
||||
)
|
||||
|
||||
|
||||
class ExtractReview(pyblish.api.InstancePlugin):
|
||||
|
|
@ -43,17 +49,11 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
supported_exts = image_exts + video_exts
|
||||
|
||||
# FFmpeg tools paths
|
||||
ffmpeg_path = openpype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
ffmpeg_path = get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
# Preset attributes
|
||||
profiles = None
|
||||
|
||||
# Legacy attributes
|
||||
outputs = {}
|
||||
ext_filter = []
|
||||
to_width = 1920
|
||||
to_height = 1080
|
||||
|
||||
def process(self, instance):
|
||||
self.log.debug(instance.data["representations"])
|
||||
# Skip review when requested.
|
||||
|
|
@ -72,10 +72,6 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
).format(instance_label))
|
||||
return
|
||||
|
||||
# Use legacy processing when `profiles` is not set.
|
||||
if self.profiles is None:
|
||||
return self.legacy_process(instance)
|
||||
|
||||
# Run processing
|
||||
self.main_process(instance)
|
||||
|
||||
|
|
@ -726,7 +722,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
|
||||
# NOTE Skipped using instance's resolution
|
||||
full_input_path_single_file = temp_data["full_input_path_single_file"]
|
||||
input_data = openpype.lib.ffprobe_streams(
|
||||
input_data = ffprobe_streams(
|
||||
full_input_path_single_file, self.log
|
||||
)[0]
|
||||
input_width = int(input_data["width"])
|
||||
|
|
@ -1253,438 +1249,6 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
|
||||
return filtered_outputs
|
||||
|
||||
def legacy_process(self, instance):
|
||||
self.log.warning("Legacy review presets are used.")
|
||||
|
||||
output_profiles = self.outputs or {}
|
||||
|
||||
inst_data = instance.data
|
||||
context_data = instance.context.data
|
||||
fps = float(inst_data.get("fps"))
|
||||
frame_start = inst_data.get("frameStart")
|
||||
frame_end = inst_data.get("frameEnd")
|
||||
handle_start = inst_data.get("handleStart",
|
||||
context_data.get("handleStart"))
|
||||
handle_end = inst_data.get("handleEnd",
|
||||
context_data.get("handleEnd"))
|
||||
pixel_aspect = inst_data.get("pixelAspect", 1)
|
||||
resolution_width = inst_data.get("resolutionWidth", self.to_width)
|
||||
resolution_height = inst_data.get("resolutionHeight", self.to_height)
|
||||
self.log.debug("Families In: `{}`".format(inst_data["families"]))
|
||||
self.log.debug("__ frame_start: {}".format(frame_start))
|
||||
self.log.debug("__ frame_end: {}".format(frame_end))
|
||||
self.log.debug("__ handle_start: {}".format(handle_start))
|
||||
self.log.debug("__ handle_end: {}".format(handle_end))
|
||||
|
||||
# get representation and loop them
|
||||
representations = inst_data["representations"]
|
||||
|
||||
ffmpeg_path = openpype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
# filter out mov and img sequences
|
||||
representations_new = representations[:]
|
||||
for repre in representations:
|
||||
|
||||
if repre['ext'] not in self.ext_filter:
|
||||
continue
|
||||
|
||||
tags = repre.get("tags", [])
|
||||
|
||||
if inst_data.get("multipartExr") is True:
|
||||
# ffmpeg doesn't support multipart exrs
|
||||
continue
|
||||
|
||||
if "thumbnail" in tags:
|
||||
continue
|
||||
|
||||
self.log.info("Try repre: {}".format(repre))
|
||||
|
||||
if "review" not in tags:
|
||||
continue
|
||||
|
||||
staging_dir = repre["stagingDir"]
|
||||
|
||||
# iterating preset output profiles
|
||||
for name, profile in output_profiles.items():
|
||||
repre_new = repre.copy()
|
||||
ext = profile.get("ext", None)
|
||||
p_tags = profile.get('tags', [])
|
||||
|
||||
# append repre tags into profile tags
|
||||
for t in tags:
|
||||
if t not in p_tags:
|
||||
p_tags.append(t)
|
||||
|
||||
self.log.info("p_tags: `{}`".format(p_tags))
|
||||
|
||||
# adding control for presets to be sequence
|
||||
# or single file
|
||||
is_sequence = ("sequence" in p_tags) and (ext in (
|
||||
"png", "jpg", "jpeg"))
|
||||
|
||||
# no handles switch from profile tags
|
||||
no_handles = "no-handles" in p_tags
|
||||
|
||||
self.log.debug("Profile name: {}".format(name))
|
||||
|
||||
if not ext:
|
||||
ext = "mov"
|
||||
self.log.warning(
|
||||
str("`ext` attribute not in output "
|
||||
"profile. Setting to default ext: `mov`"))
|
||||
|
||||
self.log.debug(
|
||||
"instance.families: {}".format(
|
||||
instance.data['families']))
|
||||
self.log.debug(
|
||||
"profile.families: {}".format(profile['families']))
|
||||
|
||||
profile_family_check = False
|
||||
for _family in profile['families']:
|
||||
if _family in instance.data['families']:
|
||||
profile_family_check = True
|
||||
break
|
||||
|
||||
if not profile_family_check:
|
||||
continue
|
||||
|
||||
if isinstance(repre["files"], list):
|
||||
collections, remainder = clique.assemble(
|
||||
repre["files"])
|
||||
|
||||
full_input_path = os.path.join(
|
||||
staging_dir, collections[0].format(
|
||||
'{head}{padding}{tail}')
|
||||
)
|
||||
|
||||
filename = collections[0].format('{head}')
|
||||
if filename.endswith('.'):
|
||||
filename = filename[:-1]
|
||||
else:
|
||||
full_input_path = os.path.join(
|
||||
staging_dir, repre["files"])
|
||||
filename = repre["files"].split(".")[0]
|
||||
|
||||
repr_file = filename + "_{0}.{1}".format(name, ext)
|
||||
full_output_path = os.path.join(
|
||||
staging_dir, repr_file)
|
||||
|
||||
if is_sequence:
|
||||
filename_base = filename + "_{0}".format(name)
|
||||
repr_file = filename_base + ".%08d.{0}".format(
|
||||
ext)
|
||||
repre_new["sequence_file"] = repr_file
|
||||
full_output_path = os.path.join(
|
||||
staging_dir, filename_base, repr_file)
|
||||
|
||||
self.log.info("input {}".format(full_input_path))
|
||||
self.log.info("output {}".format(full_output_path))
|
||||
|
||||
new_tags = [x for x in tags if x != "delete"]
|
||||
|
||||
# add families
|
||||
[instance.data["families"].append(t)
|
||||
for t in p_tags
|
||||
if t not in instance.data["families"]]
|
||||
|
||||
# add to
|
||||
[new_tags.append(t) for t in p_tags
|
||||
if t not in new_tags]
|
||||
|
||||
self.log.info("new_tags: `{}`".format(new_tags))
|
||||
|
||||
input_args = []
|
||||
output_args = []
|
||||
|
||||
# overrides output file
|
||||
input_args.append("-y")
|
||||
|
||||
# preset's input data
|
||||
input_args.extend(profile.get('input', []))
|
||||
|
||||
# necessary input data
|
||||
# adds start arg only if image sequence
|
||||
|
||||
frame_start_handle = frame_start - handle_start
|
||||
frame_end_handle = frame_end + handle_end
|
||||
if isinstance(repre["files"], list):
|
||||
if frame_start_handle != repre.get(
|
||||
"detectedStart", frame_start_handle):
|
||||
frame_start_handle = repre.get("detectedStart")
|
||||
|
||||
# exclude handle if no handles defined
|
||||
if no_handles:
|
||||
frame_start_handle = frame_start
|
||||
frame_end_handle = frame_end
|
||||
|
||||
input_args.append(
|
||||
"-start_number {0} -framerate {1}".format(
|
||||
frame_start_handle, fps))
|
||||
else:
|
||||
if no_handles:
|
||||
start_sec = float(handle_start) / fps
|
||||
input_args.append("-ss {:0.2f}".format(start_sec))
|
||||
frame_start_handle = frame_start
|
||||
frame_end_handle = frame_end
|
||||
|
||||
input_args.append("-i {}".format(full_input_path))
|
||||
|
||||
for audio in instance.data.get("audio", []):
|
||||
offset_frames = (
|
||||
instance.data.get("frameStartFtrack") -
|
||||
audio["offset"]
|
||||
)
|
||||
offset_seconds = offset_frames / fps
|
||||
|
||||
if offset_seconds > 0:
|
||||
input_args.append("-ss")
|
||||
else:
|
||||
input_args.append("-itsoffset")
|
||||
|
||||
input_args.append(str(abs(offset_seconds)))
|
||||
|
||||
input_args.extend(
|
||||
["-i", audio["filename"]]
|
||||
)
|
||||
|
||||
# Need to merge audio if there are more
|
||||
# than 1 input.
|
||||
if len(instance.data["audio"]) > 1:
|
||||
input_args.extend(
|
||||
[
|
||||
"-filter_complex",
|
||||
"amerge",
|
||||
"-ac",
|
||||
"2"
|
||||
]
|
||||
)
|
||||
|
||||
codec_args = profile.get('codec', [])
|
||||
output_args.extend(codec_args)
|
||||
# preset's output data
|
||||
output_args.extend(profile.get('output', []))
|
||||
|
||||
# defining image ratios
|
||||
resolution_ratio = (
|
||||
float(resolution_width) * pixel_aspect) / resolution_height
|
||||
delivery_ratio = float(self.to_width) / float(self.to_height)
|
||||
self.log.debug(
|
||||
"__ resolution_ratio: `{}`".format(resolution_ratio))
|
||||
self.log.debug(
|
||||
"__ delivery_ratio: `{}`".format(delivery_ratio))
|
||||
|
||||
# get scale factor
|
||||
scale_factor = float(self.to_height) / (
|
||||
resolution_height * pixel_aspect)
|
||||
|
||||
# shorten two decimals long float number for testing conditions
|
||||
resolution_ratio_test = float(
|
||||
"{:0.2f}".format(resolution_ratio))
|
||||
delivery_ratio_test = float(
|
||||
"{:0.2f}".format(delivery_ratio))
|
||||
|
||||
if resolution_ratio_test != delivery_ratio_test:
|
||||
scale_factor = float(self.to_width) / (
|
||||
resolution_width * pixel_aspect)
|
||||
if int(scale_factor * 100) == 100:
|
||||
scale_factor = (
|
||||
float(self.to_height) / resolution_height
|
||||
)
|
||||
|
||||
self.log.debug("__ scale_factor: `{}`".format(scale_factor))
|
||||
|
||||
# letter_box
|
||||
lb = profile.get('letter_box', 0)
|
||||
if lb != 0:
|
||||
ffmpeg_width = self.to_width
|
||||
ffmpeg_height = self.to_height
|
||||
if "reformat" not in p_tags:
|
||||
lb /= pixel_aspect
|
||||
if resolution_ratio_test != delivery_ratio_test:
|
||||
ffmpeg_width = resolution_width
|
||||
ffmpeg_height = int(
|
||||
resolution_height * pixel_aspect)
|
||||
else:
|
||||
if resolution_ratio_test != delivery_ratio_test:
|
||||
lb /= scale_factor
|
||||
else:
|
||||
lb /= pixel_aspect
|
||||
|
||||
output_args.append(str(
|
||||
"-filter:v scale={0}x{1}:flags=lanczos,"
|
||||
"setsar=1,drawbox=0:0:iw:"
|
||||
"round((ih-(iw*(1/{2})))/2):t=fill:"
|
||||
"c=black,drawbox=0:ih-round((ih-(iw*("
|
||||
"1/{2})))/2):iw:round((ih-(iw*(1/{2})))"
|
||||
"/2):t=fill:c=black").format(
|
||||
ffmpeg_width, ffmpeg_height, lb))
|
||||
|
||||
# In case audio is longer than video.
|
||||
output_args.append("-shortest")
|
||||
|
||||
if no_handles:
|
||||
duration_sec = float(
|
||||
frame_end_handle - frame_start_handle + 1) / fps
|
||||
|
||||
output_args.append("-t {:0.2f}".format(duration_sec))
|
||||
|
||||
# output filename
|
||||
output_args.append(full_output_path)
|
||||
|
||||
self.log.debug(
|
||||
"__ pixel_aspect: `{}`".format(pixel_aspect))
|
||||
self.log.debug(
|
||||
"__ resolution_width: `{}`".format(
|
||||
resolution_width))
|
||||
self.log.debug(
|
||||
"__ resolution_height: `{}`".format(
|
||||
resolution_height))
|
||||
|
||||
# scaling none square pixels and 1920 width
|
||||
if "reformat" in p_tags:
|
||||
if resolution_ratio_test < delivery_ratio_test:
|
||||
self.log.debug("lower then delivery")
|
||||
width_scale = int(self.to_width * scale_factor)
|
||||
width_half_pad = int((
|
||||
self.to_width - width_scale) / 2)
|
||||
height_scale = self.to_height
|
||||
height_half_pad = 0
|
||||
else:
|
||||
self.log.debug("heigher then delivery")
|
||||
width_scale = self.to_width
|
||||
width_half_pad = 0
|
||||
scale_factor = float(self.to_width) / (float(
|
||||
resolution_width) * pixel_aspect)
|
||||
self.log.debug(
|
||||
"__ scale_factor: `{}`".format(
|
||||
scale_factor))
|
||||
height_scale = int(
|
||||
resolution_height * scale_factor)
|
||||
height_half_pad = int(
|
||||
(self.to_height - height_scale) / 2)
|
||||
|
||||
self.log.debug(
|
||||
"__ width_scale: `{}`".format(width_scale))
|
||||
self.log.debug(
|
||||
"__ width_half_pad: `{}`".format(
|
||||
width_half_pad))
|
||||
self.log.debug(
|
||||
"__ height_scale: `{}`".format(
|
||||
height_scale))
|
||||
self.log.debug(
|
||||
"__ height_half_pad: `{}`".format(
|
||||
height_half_pad))
|
||||
|
||||
scaling_arg = str(
|
||||
"scale={0}x{1}:flags=lanczos,"
|
||||
"pad={2}:{3}:{4}:{5}:black,setsar=1"
|
||||
).format(width_scale, height_scale,
|
||||
self.to_width, self.to_height,
|
||||
width_half_pad,
|
||||
height_half_pad
|
||||
)
|
||||
|
||||
vf_back = self.add_video_filter_args(
|
||||
output_args, scaling_arg)
|
||||
# add it to output_args
|
||||
output_args.insert(0, vf_back)
|
||||
|
||||
# baking lut file application
|
||||
lut_path = instance.data.get("lutPath")
|
||||
if lut_path and ("bake-lut" in p_tags):
|
||||
# removing Gama info as it is all baked in lut
|
||||
gamma = next((g for g in input_args
|
||||
if "-gamma" in g), None)
|
||||
if gamma:
|
||||
input_args.remove(gamma)
|
||||
|
||||
# create lut argument
|
||||
lut_arg = "lut3d=file='{}'".format(
|
||||
lut_path.replace(
|
||||
"\\", "/").replace(":/", "\\:/")
|
||||
)
|
||||
lut_arg += ",colormatrix=bt601:bt709"
|
||||
|
||||
vf_back = self.add_video_filter_args(
|
||||
output_args, lut_arg)
|
||||
# add it to output_args
|
||||
output_args.insert(0, vf_back)
|
||||
self.log.info("Added Lut to ffmpeg command")
|
||||
self.log.debug(
|
||||
"_ output_args: `{}`".format(output_args))
|
||||
|
||||
if is_sequence:
|
||||
stg_dir = os.path.dirname(full_output_path)
|
||||
|
||||
if not os.path.exists(stg_dir):
|
||||
self.log.debug(
|
||||
"creating dir: {}".format(stg_dir))
|
||||
os.mkdir(stg_dir)
|
||||
|
||||
mov_args = [
|
||||
"\"{}\"".format(ffmpeg_path),
|
||||
" ".join(input_args),
|
||||
" ".join(output_args)
|
||||
]
|
||||
subprcs_cmd = " ".join(mov_args)
|
||||
|
||||
# run subprocess
|
||||
self.log.debug("Executing: {}".format(subprcs_cmd))
|
||||
openpype.api.run_subprocess(
|
||||
subprcs_cmd, shell=True, logger=self.log
|
||||
)
|
||||
|
||||
# create representation data
|
||||
repre_new.update({
|
||||
'name': name,
|
||||
'ext': ext,
|
||||
'files': repr_file,
|
||||
"tags": new_tags,
|
||||
"outputName": name,
|
||||
"codec": codec_args,
|
||||
"_profile": profile,
|
||||
"resolutionHeight": resolution_height,
|
||||
"resolutionWidth": resolution_width,
|
||||
"frameStartFtrack": frame_start_handle,
|
||||
"frameEndFtrack": frame_end_handle
|
||||
})
|
||||
if is_sequence:
|
||||
repre_new.update({
|
||||
"stagingDir": stg_dir,
|
||||
"files": os.listdir(stg_dir)
|
||||
})
|
||||
if no_handles:
|
||||
repre_new.update({
|
||||
"outputName": name + "_noHandles",
|
||||
"frameStartFtrack": frame_start,
|
||||
"frameEndFtrack": frame_end
|
||||
})
|
||||
if repre_new.get('preview'):
|
||||
repre_new.pop("preview")
|
||||
if repre_new.get('thumbnail'):
|
||||
repre_new.pop("thumbnail")
|
||||
|
||||
# adding representation
|
||||
self.log.debug("Adding: {}".format(repre_new))
|
||||
representations_new.append(repre_new)
|
||||
|
||||
for repre in representations_new:
|
||||
if "delete" in repre.get("tags", []):
|
||||
representations_new.remove(repre)
|
||||
if "clean_name" in repre.get("tags", []):
|
||||
repre_new.pop("outputName")
|
||||
|
||||
instance.data.update({
|
||||
"reviewToWidth": self.to_width,
|
||||
"reviewToHeight": self.to_height
|
||||
})
|
||||
|
||||
self.log.debug(
|
||||
"new representations: {}".format(representations_new))
|
||||
instance.data["representations"] = representations_new
|
||||
|
||||
self.log.debug("Families Out: `{}`".format(instance.data["families"]))
|
||||
|
||||
def add_video_filter_args(self, args, inserting_arg):
|
||||
"""
|
||||
Fixing video filter arguments to be one long string
|
||||
|
|
|
|||
|
|
@ -262,7 +262,10 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
self.lines[line] = [item]
|
||||
line += 1
|
||||
else:
|
||||
self.lines[line].append(item)
|
||||
if line in self.lines:
|
||||
self.lines[line].append(item)
|
||||
else:
|
||||
self.lines[line] = [item]
|
||||
left_x = left_x + width + self.item_spacing
|
||||
|
||||
self.update()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue