Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

[QUAD] Enhancement: Multi-thread the convert_colorspace method #6307

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 66 additions & 36 deletions openpype/lib/transcoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import xml.etree.ElementTree

from multiprocessing.pool import ThreadPool

from .execute import run_subprocess
from .vendor_bin_utils import (
get_ffmpeg_tool_args,
Expand Down Expand Up @@ -1134,50 +1136,78 @@ def convert_colorspace(
if logger is None:
logger = logging.getLogger(__name__)

input_info = get_oiio_info_for_input(input_path, logger=logger)
def get_chunks(frame_start, frame_end, chunk_size):
"""Chunk the frame numbers into groups."""
frames = list(range(frame_start, frame_end + 1))
chunk_list = [frames[i:i + chunk_size] for i in range(0, len(frames), chunk_size)]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (90 > 79 characters)

return chunk_list

# Collect channels to export
input_arg, channels_arg = get_oiio_input_and_channel_args(input_info)
def process_conversion(in_path, out_path, start_frame=None, end_frame=None):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)

if start_frame is not None:
frame_group = f'.{start_frame}-{end_frame}#.'
frame_regex = r'\.\d+-\d+#\.'
in_path = re.sub(frame_regex, frame_group, in_path)
out_path = re.sub(frame_regex, frame_group, out_path)

# Prepare subprocess arguments
oiio_cmd = get_oiio_tool_args(
"oiiotool",
# Don't add any additional attributes
"--nosoftwareattrib",
"--colorconfig", config_path
)
input_info = get_oiio_info_for_input(in_path, logger=logger)

oiio_cmd.extend([
input_arg, input_path,
# Tell oiiotool which channels should be put to top stack
# (and output)
"--ch", channels_arg,
# Use first subimage
"--subimage", "0"
])
# Collect channels to export
input_arg, channels_arg = get_oiio_input_and_channel_args(input_info)

# Prepare subprocess arguments
oiio_cmd = get_oiio_tool_args(
"oiiotool",
# Don't add any additional attributes
"--nosoftwareattrib",
"--colorconfig", config_path
)

oiio_cmd.extend([
input_arg, in_path,
# Tell oiiotool which channels should be put to top stack
# (and output)
"--ch", channels_arg,
# Use first subimage
"--subimage", "0"
])

if all([target_colorspace, view, display]):
raise ValueError("Colorspace and both screen and display"
" cannot be set together."
"Choose colorspace or screen and display")
if not target_colorspace and not all([view, display]):
raise ValueError("Both screen and display must be set.")
if all([target_colorspace, view, display]):
raise ValueError("Colorspace and both screen and display"
" cannot be set together."
"Choose colorspace or screen and display")
if not target_colorspace and not all([view, display]):
raise ValueError("Both screen and display must be set.")

if additional_command_args:
oiio_cmd.extend(additional_command_args)
if additional_command_args:
oiio_cmd.extend(additional_command_args)

if target_colorspace:
oiio_cmd.extend(["--colorconvert",
source_colorspace,
target_colorspace])
if view and display:
oiio_cmd.extend(["--iscolorspace", source_colorspace])
oiio_cmd.extend(["--ociodisplay", display, view])
if target_colorspace:
oiio_cmd.extend(["--colorconvert",
source_colorspace,
target_colorspace])
if view and display:
oiio_cmd.extend(["--iscolorspace", source_colorspace])
oiio_cmd.extend(["--ociodisplay", display, view])

oiio_cmd.extend(["-o", output_path])
oiio_cmd.extend(["-o", out_path])

logger.debug("Conversion command: {}".format(" ".join(oiio_cmd)))
run_subprocess(oiio_cmd, logger=logger)
logger.debug("Conversion command: {}".format(" ".join(oiio_cmd)))
run_subprocess(oiio_cmd, logger=logger)

frame_data = input_path.split('.')[-2]
# If it's a range of frames, we multithread it
if '-' in frame_data:
start, end = frame_data[:-1].split('-')
# chunk_size could be editable
chunks = get_chunks(int(start), int(end), chunk_size=10)

pool = ThreadPool()
for chunk in chunks:
pool.apply_async(process_conversion, (input_path, output_path, chunk[0], chunk[-1]))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (96 > 79 characters)

pool.close()
pool.join()
else:
process_conversion(input_path, output_path)


def split_cmd_args(in_args):
Expand Down
Loading