summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorAaron Boxer <boxerab@protonmail.com>2026-04-11 09:31:58 -0400
committerCarl Hetherington <cth@carlh.net>2026-04-11 17:22:01 +0200
commit1b33fb3d1e17b859dc5166cb4d0783b17c60becf (patch)
treedffa34c4340fd52af3f43bc7feaeb68040baafe5 /src/lib
parentd9e0bff92f54aa1b7e9ff667cdce4dc8243c5219 (diff)
Grok: fix hang when encoding with burned-in subtitles and no colour conversion
When a source has no colour conversion (e.g. an already-XYZ J2K DCP), every frame normally bypasses encoding via the has_j2k() fast-path. But has_j2k() returns false as soon as _text is set, so the first burned-subtitle frame goes through the encode path and hits the colour_conversion assertion in the Grok variant of convert_to_xyz(), killing the Grok threads one by one until the queue can no longer drain. Handle the no-conversion case the same way the local convert_to_xyz() overload does: the image is already XYZ12LE, so copy it straight into the destination buffer.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dcp_video.cc34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/lib/dcp_video.cc b/src/lib/dcp_video.cc
index 775298091..66f4a3c4c 100644
--- a/src/lib/dcp_video.cc
+++ b/src/lib/dcp_video.cc
@@ -135,16 +135,32 @@ DCPVideo::get_size() const
void
DCPVideo::convert_to_xyz(uint16_t* dst) const
{
- DCPOMATIC_ASSERT(_frame->colour_conversion());
+ auto conversion = [](AVPixelFormat fmt) {
+ return fmt == AV_PIX_FMT_XYZ12LE ? AV_PIX_FMT_XYZ12LE : AV_PIX_FMT_RGB48LE;
+ };
- auto image = _frame->image(force(AV_PIX_FMT_RGB48LE), VideoRange::FULL, false);
- dcp::rgb_to_xyz(
- image->data()[0],
- dst,
- image->size(),
- image->stride()[0],
- _frame->colour_conversion().get()
- );
+ auto image = _frame->image(conversion, VideoRange::FULL, false);
+
+ if (_frame->colour_conversion()) {
+ dcp::rgb_to_xyz(
+ image->data()[0],
+ dst,
+ image->size(),
+ image->stride()[0],
+ _frame->colour_conversion().get()
+ );
+ } else {
+ auto const size = image->size();
+ auto const row_bytes = static_cast<size_t>(size.width) * 3 * sizeof(uint16_t);
+ auto src = image->data()[0];
+ auto const src_stride = image->stride()[0];
+ auto out = reinterpret_cast<uint8_t*>(dst);
+ for (int y = 0; y < size.height; ++y) {
+ memcpy(out, src, row_bytes);
+ src += src_stride;
+ out += row_bytes;
+ }
+ }
}