diff options
| author | Carl Hetherington <cth@carlh.net> | 2022-08-11 23:42:01 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2022-08-11 23:48:40 +0200 |
| commit | 2e607b7968a0af94d7e38fb9d7d5459e33beed85 (patch) | |
| tree | 0069869c5160b8dc7c705b596b70b19eeab22ba2 /src/lib | |
| parent | da75178e689a48dc689b70e0880a45f0cf8c07a8 (diff) | |
Fix video range in preview and DCP when source is VIDEO rather than FULL.video-range-bug
It looks like the handling of "video" range (16-235) sources (when
creating "full" range (0-255) outputs) has been broken for some considerable
time. Full range outputs are used for both preview and DCP creation.
We assumed that after we called sws_setColorspaceDetails FFmpeg would take
care of the conversion from video to full, but its source suggests that
it refuses to convert to full-range RGB (only full-range YUV or
greyscale). Previously there was a seemingly correct comment (that
FFmpeg would do nothing if source _or_ destination were RGB) but the
check on when to use video_range_to_full_range() was only activated
for RGB sources, not (also) RGB outputs.
It's hard to believe that this has been around unnoticed for so long.
https://dcpomatic.com/forum/viewtopic.php?t=1928&start=10 has a
discussion which pointed out the problem.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/image.cc | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/lib/image.cc b/src/lib/image.cc index 5866ee5b4..dfa093fbe 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -249,7 +249,7 @@ Image::crop_scale_window ( 1 -> destination range JPEG (i.e. "full", 0-255) But remember: sws_setColorspaceDetails ignores these - parameters unless the both source and destination images + parameters unless both source and destination images are isYUV or isGray. (If either is not, it uses video range). */ sws_setColorspaceDetails ( @@ -307,9 +307,12 @@ Image::crop_scale_window ( if ( video_range == VideoRange::VIDEO && out_video_range == VideoRange::FULL && - av_pix_fmt_desc_get(_pixel_format)->flags & AV_PIX_FMT_FLAG_RGB + ((av_pix_fmt_desc_get(_pixel_format)->flags & AV_PIX_FMT_FLAG_RGB) || + (av_pix_fmt_desc_get(out_format)->flags & AV_PIX_FMT_FLAG_RGB)) ) { - /* libswscale will not convert video range for RGB sources, so we have to do it ourselves */ + /* libswscale will not convert video range if input or output is RGB, as far as I can see, + * so we have to do it ourselves. + */ out->video_range_to_full_range (); } |
