From 7cf4e085f7c00ff8a9af2fdf538d7b0aed88f566 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 2 Nov 2022 12:19:02 +0100 Subject: [PATCH 1/7] handle more types --- openpype/lib/transcoding.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index e736ba8ef0..4fc3a7ce94 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -111,6 +111,7 @@ def get_oiio_info_for_input(filepath, logger=None): class RationalToInt: """Rational value stored as division of 2 integers using string.""" + def __init__(self, string_value): parts = string_value.split("/") top = float(parts[0]) @@ -157,16 +158,16 @@ def convert_value_by_type_name(value_type, value, logger=None): if value_type == "int": return int(value) - if value_type == "float": + if value_type in ("float", "double"): return float(value) # Vectors will probably have more types - if value_type in ("vec2f", "float2"): + if value_type in ("vec2f", "float2", "float2d"): return [float(item) for item in value.split(",")] # Matrix should be always have square size of element 3x3, 4x4 # - are returned as list of lists - if value_type == "matrix": + if value_type in ("matrix", "matrixd"): output = [] current_index = -1 parts = value.split(",") @@ -198,7 +199,7 @@ def convert_value_by_type_name(value_type, value, logger=None): if value_type == "rational2i": return RationalToInt(value) - if value_type == "vector": + if value_type in ("vector", "vectord"): parts = [part.strip() for part in value.split(",")] output = [] for part in parts: From 7aca8136f5ba0ab22fd0e6084d5cc2901ac791a1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 2 Nov 2022 12:19:32 +0100 Subject: [PATCH 2/7] 'get_oiio_info_for_input' can return information about all subimages --- openpype/lib/transcoding.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 4fc3a7ce94..9d87818508 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -77,26 +77,38 @@ def get_transcode_temp_directory(): ) -def get_oiio_info_for_input(filepath, logger=None): +def get_oiio_info_for_input(filepath, logger=None, subimages=False): """Call oiiotool to get information about input and return stdout. Stdout should contain xml format string. """ args = [ - get_oiio_tools_path(), "--info", "-v", "-i:infoformat=xml", filepath + get_oiio_tools_path(), + "--info", + "-v" ] + if subimages: + args.append("-a") + + args.extend(["-i:infoformat=xml", filepath]) + output = run_subprocess(args, logger=logger) output = output.replace("\r\n", "\n") xml_started = False + subimages = [] lines = [] for line in output.split("\n"): if not xml_started: if not line.startswith("<"): continue xml_started = True + if xml_started: lines.append(line) + if line == "": + subimages.append(lines) + lines = [] if not xml_started: raise ValueError( @@ -105,8 +117,14 @@ def get_oiio_info_for_input(filepath, logger=None): ) ) - xml_text = "\n".join(lines) - return parse_oiio_xml_output(xml_text, logger=logger) + output = [] + for subimage in subimages: + xml_text = "\n".join(subimage) + output.append(parse_oiio_xml_output(xml_text, logger=logger)) + + if subimages: + return output + return output[0] class RationalToInt: From 61d9657ce16e9eb3b4a434368cb316d2bf8ac05a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 2 Nov 2022 12:20:58 +0100 Subject: [PATCH 3/7] subimages are reason for conversion and skip definition of input channels if there are subimages --- openpype/lib/transcoding.py | 39 +++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 9d87818508..32c71fee7e 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -399,6 +399,10 @@ def should_convert_for_ffmpeg(src_filepath): if not input_info: return None + subimages = input_info.get("subimages") + if subimages is not None and subimages > 1: + return True + # Check compression compression = input_info["attribs"].get("compression") if compression in ("dwaa", "dwab"): @@ -507,13 +511,23 @@ def convert_for_ffmpeg( input_channels.append(alpha) input_channels_str = ",".join(input_channels) - oiio_cmd.extend([ + subimages = input_info.get("subimages") + input_arg = "-i" + if subimages is None or subimages == 1: # Tell oiiotool which channels should be loaded # - other channels are not loaded to memory so helps to avoid memory # leak issues - "-i:ch={}".format(input_channels_str), first_input_path, + # - this option is crashing if used on multipart/subimages exrs + input_arg += ":ch={}".format(input_channels_str) + + oiio_cmd.extend([ + input_arg, first_input_path, # Tell oiiotool which channels should be put to top stack (and output) - "--ch", channels_arg + "--ch", channels_arg, + # Use first subimage + # TODO we should look for all subimages and try (somehow) find the + # best candidate for output + "--subimage", "0" ]) # Add frame definitions to arguments @@ -631,6 +645,15 @@ def convert_input_paths_for_ffmpeg( input_channels.append(alpha) input_channels_str = ",".join(input_channels) + subimages = input_info.get("subimages") + input_arg = "-i" + if subimages is None or subimages == 1: + # Tell oiiotool which channels should be loaded + # - other channels are not loaded to memory so helps to avoid memory + # leak issues + # - this option is crashing if used on multipart/subimages exrs + input_arg += ":ch={}".format(input_channels_str) + for input_path in input_paths: # Prepare subprocess arguments oiio_cmd = [ @@ -644,13 +667,13 @@ def convert_input_paths_for_ffmpeg( oiio_cmd.extend(["--compression", compression]) oiio_cmd.extend([ - # Tell oiiotool which channels should be loaded - # - other channels are not loaded to memory so helps to - # avoid memory leak issues - "-i:ch={}".format(input_channels_str), input_path, + input_arg, input_path, # Tell oiiotool which channels should be put to top stack # (and output) - "--ch", channels_arg + "--ch", channels_arg, + # Use first subimage + # TODO we should look for all subimages and try (somehow) find the + "--subimage", "0" ]) for attr_name, attr_value in input_info["attribs"].items(): From f437ce7c983cd30a37c3ed697e73d670a79fa87f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 2 Nov 2022 16:37:26 +0100 Subject: [PATCH 4/7] fix variable names --- openpype/lib/transcoding.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 32c71fee7e..1ab3cb4081 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -96,7 +96,7 @@ def get_oiio_info_for_input(filepath, logger=None, subimages=False): output = output.replace("\r\n", "\n") xml_started = False - subimages = [] + subimages_lines = [] lines = [] for line in output.split("\n"): if not xml_started: @@ -107,7 +107,7 @@ def get_oiio_info_for_input(filepath, logger=None, subimages=False): if xml_started: lines.append(line) if line == "": - subimages.append(lines) + subimages_lines.append(lines) lines = [] if not xml_started: @@ -118,8 +118,8 @@ def get_oiio_info_for_input(filepath, logger=None, subimages=False): ) output = [] - for subimage in subimages: - xml_text = "\n".join(subimage) + for subimage_lines in subimages_lines: + xml_text = "\n".join(subimage_lines) output.append(parse_oiio_xml_output(xml_text, logger=logger)) if subimages: @@ -651,7 +651,7 @@ def convert_input_paths_for_ffmpeg( # Tell oiiotool which channels should be loaded # - other channels are not loaded to memory so helps to avoid memory # leak issues - # - this option is crashing if used on multipart/subimages exrs + # - this option is crashing if used on multipart exrs input_arg += ":ch={}".format(input_channels_str) for input_path in input_paths: From 560f327de1cbbff29db576c382f2191844855338 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 2 Nov 2022 16:38:57 +0100 Subject: [PATCH 5/7] comment out subimage --- openpype/lib/transcoding.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 1ab3cb4081..af40fa752c 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -524,10 +524,10 @@ def convert_for_ffmpeg( input_arg, first_input_path, # Tell oiiotool which channels should be put to top stack (and output) "--ch", channels_arg, + # WARNING: This is commented out because ffmpeg won't be able to + # render proper output when only one subimage is outputed with oiio # Use first subimage - # TODO we should look for all subimages and try (somehow) find the - # best candidate for output - "--subimage", "0" + # "--subimage", "0" ]) # Add frame definitions to arguments @@ -671,9 +671,10 @@ def convert_input_paths_for_ffmpeg( # Tell oiiotool which channels should be put to top stack # (and output) "--ch", channels_arg, + # WARNING: This is commented out because ffmpeg won't be able to + # render proper output when only one subimage is outputed with oiio # Use first subimage - # TODO we should look for all subimages and try (somehow) find the - "--subimage", "0" + # "--subimage", "0" ]) for attr_name, attr_value in input_info["attribs"].items(): From ebbf827f0866b05d3d0915a6cb7f86f1bf814fa6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 2 Nov 2022 16:43:11 +0100 Subject: [PATCH 6/7] fix line length --- openpype/lib/transcoding.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index af40fa752c..5a57026496 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -672,7 +672,8 @@ def convert_input_paths_for_ffmpeg( # (and output) "--ch", channels_arg, # WARNING: This is commented out because ffmpeg won't be able to - # render proper output when only one subimage is outputed with oiio + # render proper output when only one subimage is outputed + # with oiiotool # Use first subimage # "--subimage", "0" ]) From 5c37d91138332442fa1d746003f8b16a7e623f2e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 16 Nov 2022 17:20:44 +0100 Subject: [PATCH 7/7] uncomment subimages because multipart exr is created which actually can't ffmpeg handle --- openpype/lib/transcoding.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 5a57026496..6f571ea522 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -476,7 +476,7 @@ def convert_for_ffmpeg( if input_frame_start is not None and input_frame_end is not None: is_sequence = int(input_frame_end) != int(input_frame_start) - input_info = get_oiio_info_for_input(first_input_path) + input_info = get_oiio_info_for_input(first_input_path, logger=logger) # Change compression only if source compression is "dwaa" or "dwab" # - they're not supported in ffmpeg @@ -524,10 +524,8 @@ def convert_for_ffmpeg( input_arg, first_input_path, # Tell oiiotool which channels should be put to top stack (and output) "--ch", channels_arg, - # WARNING: This is commented out because ffmpeg won't be able to - # render proper output when only one subimage is outputed with oiio # Use first subimage - # "--subimage", "0" + "--subimage", "0" ]) # Add frame definitions to arguments @@ -621,7 +619,7 @@ def convert_input_paths_for_ffmpeg( " \".exr\" extension. Got \"{}\"." ).format(ext)) - input_info = get_oiio_info_for_input(first_input_path) + input_info = get_oiio_info_for_input(first_input_path, logger=logger) # Change compression only if source compression is "dwaa" or "dwab" # - they're not supported in ffmpeg @@ -639,6 +637,7 @@ def convert_input_paths_for_ffmpeg( red, green, blue, alpha = review_channels input_channels = [red, green, blue] + # TODO find subimage inder where rgba is available for multipart exrs channels_arg = "R={},G={},B={}".format(red, green, blue) if alpha is not None: channels_arg += ",A={}".format(alpha) @@ -671,11 +670,8 @@ def convert_input_paths_for_ffmpeg( # Tell oiiotool which channels should be put to top stack # (and output) "--ch", channels_arg, - # WARNING: This is commented out because ffmpeg won't be able to - # render proper output when only one subimage is outputed - # with oiiotool # Use first subimage - # "--subimage", "0" + "--subimage", "0" ]) for attr_name, attr_value in input_info["attribs"].items():