Skip to content

Fix padding of planar 10 and 16 bit images in the resize filter - #1349

Merged
ddennedy merged 1 commit into
mltframework:masterfrom
eseifert:fix-resize-planar-high-bit-depth
Oct 25, 2026
Merged

ddennedy merged 1 commit into
mltframework:masterfrom
eseifert:fix-resize-planar-high-bit-depth

Conversation

@eseifert

Copy link
Copy Markdown
Contributor

The padding in resize_image() only handles packed formats, so only yuv420p was switched to yuv422 when the image needed padding. yuv420p10, yuv444p10 and yuv422p16 were padded as if they were packed, which garbled the whole frame, for example when rendering a portrait clip with pix_fmt=yuv420p10le in a landscape profile. Request rgba64 for these formats instead, which keeps the bit depth.

Testing: Reproduced: a 360x640 clip rendered in a 1280x720 profile with pix_fmt=yuv420p10le was completely garbled on master (PSNR 7 dB against the 8-bit render) and correctly pillarboxed with the fix (35 dB). Module tests unchanged.

The padding in resize_image() only handles packed formats, so only yuv420p was switched to yuv422 when the image needed padding. yuv420p10, yuv444p10 and yuv422p16 were padded as if they were packed, which garbled the whole frame, for example when rendering a portrait clip with pix_fmt=yuv420p10le in a landscape profile. Request rgba64 for these formats instead, which keeps the bit depth.
@ddennedy

Copy link
Copy Markdown
Member

Where are you going with this and #1350? If you are planning to submit more PRs to add >8-bit YUV formats to the MLT native filters and transitions, I want to prevent that. By design, these mlt_image_formats are not intended to be supported by filters and transitions. They are merely a means to get high bit depths into and out of MLT graphs and interface with things like Movit and Decklink. If you need to do image processing for high bit depth you should set the mlt_image_format=rgba64 on the consumer to specify a pixel format for image processing, not yuv420p10. If you did that, then you would not need this change. So, what are working on such that you need this? If it is for simple editing without processing, then this PR is sensible. The change is minimal and sensible, I just want to make sure you on the right track and avoid a bunch of work that we do not want to include.

@eseifert

Copy link
Copy Markdown
Contributor Author

Where are you going with this and #1350?

Thanks for the explanation. These PRs go the other way, though: they don't add high-bit-depth YUV processing to resize and crop. When one of those filters would have to modify a yuv420p10/yuv444p10/yuv422p16 image, it now requests rgba64 instead, the same way it already falls back from yuv420p to yuv422.

I don’t want to implement processing in yuv420p10. consumer_avformat sets mlt_image_format=yuv420p10 itself when pix_fmt=yuv420p10le, and resize/crop are normalizers that pass the requested format through. So a plain 10-bit export of a portrait clip in a landscape profile, or with any crop, is garbled today. With the change it's padded/cropped in rgba64 and comes out correct.

I came across this while testing 10-bit exports from Kdenlive. I'm not planning further PRs to add high-bit-depth YUV support to filters or transitions.

@ddennedy ddennedy added this to the v7.44.0 milestone Oct 25, 2026
@ddennedy
ddennedy merged commit 41af587 into mltframework:master Oct 25, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants