Skip to content

AY-7315_Extract Review and OIIO transcode failing to transcode media blocking publishes #989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 tasks done
BigRoy opened this issue Nov 6, 2024 · 13 comments · May be fixed by #1271
Open
2 tasks done

AY-7315_Extract Review and OIIO transcode failing to transcode media blocking publishes #989

BigRoy opened this issue Nov 6, 2024 · 13 comments · May be fixed by #1271
Assignees
Labels
sponsored This is directly sponsored by a client or community member

Comments

@BigRoy
Copy link
Collaborator

BigRoy commented Nov 6, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior:

Over time we've had annoying reports where studios were unable to publish their renders because the publishing system (due to user configuration) tries to transcode e.g. a Z-depth AOV layer which may only have a named Z or Y channel and has no R, G, B or A channels and hence we don't really know what layer to process.

Instead of this we could also implement detecting more cases, so that if RGBA is not found in the file that maybe we allow to fall back to channels:

  • XYZ
  • Y
  • Z (usually for z-depth?)

Here's metadata output for a file that fails without this PR:

<nchannels>1</nchannels>
<channelnames>
<channelname>Y</channelname>
</channelnames>
<alpha_channel>-1</alpha_channel>
<z_channel>-1</z_channel>
<deep>0</deep>

It's an Arnold Z-depth render AOV.

Error logs

2024-11-03 00:43:01:  0: STDOUT: ERROR:pyblish.plugin:Traceback (most recent call last):
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\dependency_packages\ayon_2406251801_windows.zip\dependencies\pyblish\plugin.py", line 528, in __explicit_process
2024-11-03 00:43:01:  0: STDOUT:     runner(*args)
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\addons\core_1.0.3\ayon_core\plugins\publish\extract_color_transcode.py", line 163, in process
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\addons\core_1.0.3\ayon_core\lib\transcoding.py", line 1141, in convert_colorspace
2024-11-03 00:43:01:  0: STDOUT:     input_arg, channels_arg = get_oiio_input_and_channel_args(input_info)
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\addons\core_1.0.3\ayon_core\lib\transcoding.py", line 1430, in get_oiio_input_and_channel_args
2024-11-03 00:43:01:  0: STDOUT:     raise ValueError(
2024-11-03 00:43:01:  0: STDOUT: ValueError: Couldn't find channels that can be used for conversion.
2024-11-03 00:43:01:  0: STDOUT: Traceback (most recent call last):
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\dependency_packages\ayon_2406251801_windows.zip\dependencies\pyblish\plugin.py", line 528, in __explicit_process
2024-11-03 00:43:01:  0: STDOUT:     runner(*args)
2024-11-03 00:43:01:  0: STDOUT:   File "<string>", line 163, in process
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\addons\core_1.0.3\ayon_core\lib\transcoding.py", line 1141, in convert_colorspace
2024-11-03 00:43:01:  0: STDOUT:     input_arg, channels_arg = get_oiio_input_and_channel_args(input_info)
2024-11-03 00:43:01:  0: STDOUT:   File "C:\Users\work\AppData\Local\Ynput\AYON\addons\core_1.0.3\ayon_core\lib\transcoding.py", line 1430, in get_oiio_input_and_channel_args
2024-11-03 00:43:01:  0: STDOUT:     raise ValueError(
2024-11-03 00:43:01:  0: STDOUT: ValueError: Couldn't find channels that can be used for conversion.
2024-11-03 00:43:01:  0: STDOUT: !!! ERR: 2024-11-03 00:43:01,066 >>> { CLI-publish }: [ Failed ExtractOIIOTranscode: Couldn't find channels that can be used for conversion. -- ('C:\\Users\\work\\AppData\\Local\\Ynput\\AYON\\addons\\core_1.0.3\\ayon_core\\plugins\\publish\\extract_color_transcode.py', 1430, 'get_oiio_input_and_channel_args', 'raise ValueError(') ] 

It's good to be aware that ExtractReview would also try to find a reviewable channel if it thinks it can't be processed by FFMPEG. Currently, if ExtractReview can't find a suitable RGBA channel then it'd just skip generating the reviewable for it.

However, ExtractOIIOTranscode runs before ExtractReview and would (or at least could?) usually perform the necessary conversion.

Expected Behavior:

Either:

  • Allow the transcode to 'pass' through without an error but just a logged warning.
    OR
  • Improve the channel detection to allow media to be much less unlikely to fail like this.

Version

1.0.0

What platform you are running on?

Windows

Steps To Reproduce:

  1. Create a Maya Arnold render to EXR with separate AOV (not multilayer EXR) with a Z-depth AOV

Are there any labels you wish to add?

  • I have added the relevant labels to the bug report.

Relevant log output:

No response

Additional context:

We do have settings to "filter out" certain AOVs because we've had this issue before on Extract Review. The setting is at ayon+settings://deadline/publish/ProcessSubmittedJobOnFarm/aov_filter however it does not apply to ExtractOIIOTranscode because transcode may occur on something that isn't necessarily a reviewable (I suppose?)

@BigRoy BigRoy added the type: bug Something isn't working label Nov 6, 2024
@mkolar mkolar removed the type: bug Something isn't working label Nov 6, 2024
@iLLiCiTiT iLLiCiTiT added the type: enhancement Improvement of existing functionality or minor addition label Nov 26, 2024
@BigRoy
Copy link
Collaborator Author

BigRoy commented Jan 13, 2025

Linking this prototype I once did to not raise an error but instead log a warning to at least allow continuing to publish: #988

@m-u-r-p-h-y m-u-r-p-h-y changed the title Extract Review and OIIO transcode failing to transcode media blocking publishes AY-7315_Extract Review and OIIO transcode failing to transcode media blocking publishes Jan 13, 2025
@m-u-r-p-h-y m-u-r-p-h-y added the sponsored This is directly sponsored by a client or community member label Jan 13, 2025
@tatiana-ynput tatiana-ynput assigned BigRoy and iLLiCiTiT and unassigned BigRoy Feb 3, 2025
@iLLiCiTiT
Copy link
Member

I kinda do get grasp of the problematics, but I don't know full purpose of ExtractOIIOTranscode and if we need it for 3d renders. This #988 looks like it at least does not "crash", hard to tell if it is ok?

The proper solution would probably be, that maya would pass the information about output renders to publish job, which would require massive refactor of deadline addon and all host integration addons that are using deadline as instance and representation collection should be done in host integrations (because they know what the output will be) -> this would also require some changes in ayon-core. The refactor would also probably resolve issues connected to review AOV filtering. But that is epic.

@jakubjezek001
Copy link
Member

I am also attaching here some info about SXR file format https://www.fxphd.com/fxblog/stereo-openexr-opensxr/. This is quite related to the post I was writing in discussion on our Discord thread.

I wouldn't be so sure about excluding non-RGB layers/files from OIIO processing. What if someone needs to convert EXR data passes into another format, or vice versa? I realize this is an unlikely situation, but we should remain open to possibilities and let the user decide how this could be used. Perhaps we should have some switch which would let user to decide on preset that it is only restricted to rgba or data.

@iLLiCiTiT
Copy link
Member

iLLiCiTiT commented Feb 6, 2025

I'm not sure user knows about it, he just sent renders to farm. Or I don't know if 3d artists do know what output it will create, I guess it is based on what renderer is used, and what is set in settings? In that case it is not that easy to resolve. But at the end, the plugin ExtractOIIOTranscode has 0% of information about it, we would still have to pass it to the publish job metadata file somehow, which we can't because we're guessing content of the files too. Maya addon has no way how to pass that information to publish job.

@mkolar mkolar removed the type: enhancement Improvement of existing functionality or minor addition label Feb 10, 2025
@philippe-ynput
Copy link
Contributor

philippe-ynput commented Mar 3, 2025

I have worked on that problem before. There are naming conventions originating from OpenEXR that can be used to support more than RGBA.
https://openexr.com/en/latest/TechnicalIntroduction.html#channel-names

@BigRoy
Copy link
Collaborator Author

BigRoy commented Mar 3, 2025

What if we add an additional filter to the transcode settings that is like a regex or list of channels to transcode if present - if no matching channels, leave the file as is?

@philippe-ynput
Copy link
Contributor

philippe-ynput commented Mar 3, 2025

Sure, but I think we should be able to handle single-channel files (A, Z or Y).

@BigRoy
Copy link
Collaborator Author

BigRoy commented Mar 3, 2025

Yup - which would then be what we'd add to the 'defaults' in the profiles?

It does leave the question whether you really want to "transcode" a Z channel which is usually a data channel and not in an image rendered in a colorspace that needs colorspace conversions?

@philippe-ynput
Copy link
Contributor

mmm... yes, if we want to keep things simple we should probably ignore data channels, like Z.

how would you present the new transcode settings ?

[['R', 'G', 'B', 'A'], ['r', 'g', 'b', 'a'], ['red', 'green', 'blue', 'alpha']]

@BigRoy
Copy link
Collaborator Author

BigRoy commented Mar 4, 2025

Just wanted to flag this that came up on Discord here that mentioned using --if and --endif arguments to oiiotool to make it explicit 'optional' behavior directly on the CLI of OIIO.

When you have a lot of different inputs into oiio (because Substance Painter outputs can be very different from each other), you sometimes have to deal with special cases.
For example, the webp format does not support 1-channel images. But png does.
So you could use these oiio parameters : --if "{TOP.nchannels < 3}" --ch R,G,B --endif (I think it replicates the single input channel to 3 output channels)

https://openimageio.readthedocs.io/en/stable/oiiotool.html#cmdoption-if

A workaround would be to use negative regex rules in Extract OIIO Transcode-->Profiles-->Product names, to stop conversion for some kind of textures, but then you have to know the names of all textures kinds that are 1-channel, which is really cumbersome.

AND

And also related to this one (and its comment) :
#1003

@philippe-ynput
Copy link
Contributor

philippe-ynput commented Mar 4, 2025

Good point @BigRoy. That would be even better. To be tested !

While I'm here, it looks like we could add deep image support quite easily:

File: client/ayon_core/lib/transcoding.py
730:         if input_info["attribs"].get("deep", False):
731:             # flatten deep images: they are not natively supported by ffmpeg.
732:             oiio_cmd.extend(["--flatten"])
733: 

@BigRoy
Copy link
Collaborator Author

BigRoy commented Mar 17, 2025

Just adding @jakubjezek001's note that we'll also need to support stereo EXRs and may need to specify the "view" in the transcoding.

@philippe-ynput for now - should we just add the channels choose in settings? Shall we do a quick call to discuss to get this one rolling?

@BigRoy BigRoy self-assigned this Apr 9, 2025
@BigRoy
Copy link
Collaborator Author

BigRoy commented Apr 9, 2025

The approach now will be:

  • Add channel mapping settings, so the settings would define which channels it would process. If no matching channels, the image is skipped instead of raising errors.
  • We may need separate channel mappings for R, G, B and A so that e.g. an image with just Y could be mapped to render a greyscale/luminance image.
  • We may want to use fnmatch instead of regex in settings here because it may be easier to use for artists/admins. Especially because channel names tend to also include dots.

The new defaults would then include a channel mapping that would match the current behavior so it's backwards compatible, except for it not raising an error if the image does not contain any matching channel. We'd then just log a warning most likely.

Aside of the linked OpenEXR page on channel names
these examples came up during the discussion:

  • Renderman beauty is Ci and a, see here

The default display channels are 'Ci' and 'a' (beauty and alpha)

  • Arnold Z-depth AOV renders as only Z channel, no RGBA present.

I need to create a mapping in Settings where someone can state what channels in an image should map to which channel.

Like being able to say:

  • If RGBA is present, then R=R,G=G,B=B,A=A
  • If RGB is present, then R=R,G=G,B=B,A=1
  • If Z is present, then R=Z,G=Z,B=Z
  • If Y is present, then R=Y,G=Y,B=Y

And most likely even being able to support a regex (or fnmatch), like matching anything that endswith .R
It'd basically replace this logic with an explicit mapping:

def get_review_info_by_layer_name(channel_names):
"""Get channels info grouped by layer name.
Finds all layers in channel names and returns list of dictionaries with
information about channels in layer.
Example output (not real world example):
[
{
"name": "Main",
"review_channels": {
"R": "Main.red",
"G": "Main.green",
"B": "Main.blue",
"A": None,
}
},
{
"name": "Composed",
"review_channels": {
"R": "Composed.R",
"G": "Composed.G",
"B": "Composed.B",
"A": "Composed.A",
}
},
...
]
Args:
channel_names (list[str]): List of channel names.
Returns:
list[dict]: List of channels information.
"""
layer_names_order = []
rgba_by_layer_name = collections.defaultdict(dict)
channels_by_layer_name = collections.defaultdict(dict)
for channel_name in channel_names:
layer_name = ""
last_part = channel_name
if "." in channel_name:
layer_name, last_part = channel_name.rsplit(".", 1)
channels_by_layer_name[layer_name][channel_name] = last_part
if last_part.lower() not in {
"r", "red",
"g", "green",
"b", "blue",
"a", "alpha"
}:
continue
if layer_name not in layer_names_order:
layer_names_order.append(layer_name)
# R, G, B or A
channel = last_part[0].upper()
rgba_by_layer_name[layer_name][channel] = channel_name
# Put empty layer to the beginning of the list
# - if input has R, G, B, A channels they should be used for review
if "" in layer_names_order:
layer_names_order.remove("")
layer_names_order.insert(0, "")
output = []
for layer_name in layer_names_order:
rgba_layer_info = rgba_by_layer_name[layer_name]
red = rgba_layer_info.get("R")
green = rgba_layer_info.get("G")
blue = rgba_layer_info.get("B")
if not red or not green or not blue:
continue
output.append({
"name": layer_name,
"review_channels": {
"R": red,
"G": green,
"B": blue,
"A": rgba_layer_info.get("A"),
}
})
return output

The question then becomes:

What's a decent SettingsField design for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sponsored This is directly sponsored by a client or community member
Projects
None yet
6 participants