Skip to content

Transcoding: Add handling of default DNxHD bitrates - #2064

Open
iLLiCiTiT wants to merge 3 commits into
developfrom
bugfix/dnxhd-bitrates
Open

iLLiCiTiT wants to merge 3 commits into
developfrom
bugfix/dnxhd-bitrates

Conversation

@iLLiCiTiT

Copy link
Copy Markdown
Member

Changelog Description

Added DNxHD bitrate handling when looking for ffmpeg codec arguments to copy the source as close as possible.

Additional info

The code changes were submitted by a client who did hit an issue if the bitrate was not stored in the ffmpeg arguments.

NOTE: Validate if the bitrates are actually correct.

Testing notes:

I don't know how to create review that does product DNxHD and is not going through ExtractReview.

  1. DNxHD bitrates are kept untouched even if ffmpeg arguments that created the source don't contain the bitrate information.

@iLLiCiTiT iLLiCiTiT added the type: enhancement Improvement of existing functionality or minor addition label Sep 15, 2026
@iLLiCiTiT iLLiCiTiT self-assigned this Sep 15, 2026
@ynbot ynbot added size/XS type: bug Something isn't working labels Sep 15, 2026

@BigRoy BigRoy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The fact that this is even needed. What a mess is this codec 🤮

Anyway, _DNXHD_VALID_BITRATES can do with a small comment as to what the values are supposed to be. It's clear if I read the full PR, but not if just glance over that variable.

Comment thread client/ayon_core/lib/transcoding.py Outdated
@ynbot ynbot moved this to Review In Progress in PR reviewing Sep 15, 2026
@iLLiCiTiT

Copy link
Copy Markdown
Member Author

The fact that this is even needed. What a mess is this codec

It is our fault we want to edit the video which requires to decode the video -> that means we loose all information about input and we have to try replicate it as close as possible. It is mess because it has so many options. Other codes have them too, we just don't have them in such granular way.

@BigRoy
BigRoy requested review from antirotor and jakubjezek001 and a balanced review from Copilot September 16, 2026 10:24
@BigRoy

BigRoy commented Sep 16, 2026

Copy link
Copy Markdown
Member

The code changes were submitted by a client who did hit an issue if the bitrate was not stored in the ffmpeg arguments.

Do we know how to reproduce such a scenario? 🤔

We have this in Extract Review for a client for FFMPEG arguments

{
  "video_filters": [],
  "audio_filters": [],
  "input": [],
  "output": [
    "-codec:v dnxhd",
    "-profile:v dnxhr_hq",
    "-pix_fmt yuv422p",
    "-color_range tv",
    "-colorspace bt709",
    "-color_primaries bt709",
    "-color_trc bt709",
    "-metadata reel_name={folder[name]}_{product[name]}_v{version:0>3}"
  ]
}

And that's working fine - even before this PR.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Missing metadata can suppress the required bitrate entirely, and the new selection logic lacks tests.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds DNxHD bitrate normalization when reconstructing FFmpeg codec arguments.

Changes:

  • Defines valid DNxHD bitrates by format.
  • Selects the closest valid bitrate when source arguments omit it.
File summaries
File Description
client/ayon_core/lib/transcoding.py Adds DNxHD bitrate lookup and codec argument handling.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1148 to +1158
if (
bit_rate_must_be_defined
and not bit_rate_defined
and all((pix_fmt, src_bit_rate, width, height))
):
field_order = stream_data.get("field_order", "progressive")
interlaced = field_order not in ("progressive", "unknown", "")
fixed_bit_rate = _find_closest_dnxhd_bitrate(
src_bit_rate, width, height, interlaced, pix_fmt
)
output.extend(["-b:v", fixed_bit_rate])
}


def _find_closest_dnxhd_bitrate(
@iLLiCiTiT

Copy link
Copy Markdown
Member Author

Do we know how to reproduce such a scenario?

I don't know. I guess nuke does allow to bypass core's extract review?

@rdelillo rdelillo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Confirmed it works as expected, base case-test scenario I could find was DNxHD media ingest on Hiero.
Basically extract_otio_trimming_video will call this code when ingesting a plate if the media is dnx and the clip on the timeline is shorter than the actual video range. It'll trim the input media to the shorter clip source frame range.

  • Tested DNxHD36 4:2:2 made from Nuke = all good found the closest bitrate with the function
  • Tested DNxHD350x 444 made from Nuke = not within the constant, default to stream bitrate = failed as usupported by ffmpeg

The DNxHD bitrate values within the constant looks correct according to the DNxHD specs

I didn't go through going to my version of FFmpeg and checking the constant contained ALL of the supported flavor.
Shall we do that ?

@github-project-automation github-project-automation Bot moved this from Review In Progress to Merge Requested in PR reviewing Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XS type: bug Something isn't working type: enhancement Improvement of existing functionality or minor addition

Projects

Status: Merge Requested

Development

Successfully merging this pull request may close these issues.

7 participants