diff options
| author | Aaron Boxer <boxerab@protonmail.com> | 2026-04-11 09:31:58 -0400 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2026-04-11 17:22:01 +0200 |
| commit | 1b33fb3d1e17b859dc5166cb4d0783b17c60becf (patch) | |
| tree | dffa34c4340fd52af3f43bc7feaeb68040baafe5 /src/lib | |
| parent | d9e0bff92f54aa1b7e9ff667cdce4dc8243c5219 (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.cc | 34 |
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; + } + } } |
