From 98a8023dd774fd82c144a68039e0ea3131fb9142 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 22 Jul 2025 00:48:42 +0200 Subject: New/improved pixel format decision when converting to XYZ. For a long time we would keep XYZ12LE, if that's what we have, otherwise ask FFmpeg to switch to RGB48LE. Then in 1d5c211dadb9a9dc2318adce86ca9c31b367cabe I tried to fix the case of an XYZ source mis-tagged as YUV. I changed things so that with no colour conversion we'd always ask FFmpeg to convert to XYZ. This meant that RGB sources with no colour conversion would get treatment by FFmpeg due to the RGB -> XYZ switch. Here we're going back to the more-or-less the "long time" behaviour when there is a conversion (keep XYZ12LE but otherwise convert to RGB48). When there's no conversion, keep RGB (to avoid the FFmpeg conversion from RGB -> XYZ) but convert everything else to XYZ. --- src/lib/dcp_video.cc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video.cc b/src/lib/dcp_video.cc index 823325c3e..fdbd5774f 100644 --- a/src/lib/dcp_video.cc +++ b/src/lib/dcp_video.cc @@ -49,6 +49,9 @@ #include LIBDCP_DISABLE_WARNINGS #include +extern "C" { +#include +} LIBDCP_ENABLE_WARNINGS #include #include @@ -102,7 +105,11 @@ DCPVideo::convert_to_xyz(shared_ptr frame) shared_ptr xyz; if (frame->colour_conversion()) { - auto image = frame->image(force(AV_PIX_FMT_RGB48LE), VideoRange::FULL, false); + auto conversion = [](AVPixelFormat fmt) { + return fmt == AV_PIX_FMT_XYZ12LE ? AV_PIX_FMT_XYZ12LE : AV_PIX_FMT_RGB48LE; + }; + + auto image = frame->image(conversion, VideoRange::FULL, false); xyz = dcp::rgb_to_xyz( image->data()[0], image->size(), @@ -110,7 +117,20 @@ DCPVideo::convert_to_xyz(shared_ptr frame) frame->colour_conversion().get() ); } else { - auto image = frame->image(force(AV_PIX_FMT_RGB48LE), VideoRange::FULL, false); + auto conversion = [](AVPixelFormat fmt) { + auto const descriptor = av_pix_fmt_desc_get(fmt); + if (!descriptor) { + return fmt; + } + + if (descriptor->flags & AV_PIX_FMT_FLAG_RGB) { + return AV_PIX_FMT_RGB48LE; + } + + return AV_PIX_FMT_XYZ12LE; + }; + + auto image = frame->image(conversion, VideoRange::FULL, false); xyz = make_shared(image->data()[0], image->size(), image->stride()[0]); } -- cgit v1.2.3