Improve selection of HDR content (#632)

Currently this only applies to grain synth generation,
but the prior implementation of HDR detection only looked at the props
on the input video. Those may not necessarily be set correctly even if
the user is encoding to HDR, so we want to prioritize looking at the
encoder params, then fallback to checking the input if the user has not
set a transfer characteristic on the encoder.
This commit is contained in:
Josh Holmer 2022-05-16 14:26:14 -04:00 committed by GitHub
parent fa738555c8
commit 460fa3c105
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 4 deletions

View file

@ -158,7 +158,7 @@ impl Input {
})
}
pub fn transfer_function(&self) -> anyhow::Result<TransferFunction> {
fn transfer_function(&self) -> anyhow::Result<TransferFunction> {
const FAIL_MSG: &str = "Failed to get transfer characteristics for input video";
Ok(match self {
Input::VapourSynth(video) => {
@ -180,6 +180,31 @@ impl Input {
})
}
pub fn transfer_function_params_adjusted(
&self,
enc_params: &[String],
) -> anyhow::Result<TransferFunction> {
if enc_params.iter().any(|p| {
let p = p.to_ascii_lowercase();
p == "pq" || p.ends_with("=pq") || p.ends_with("smpte2084")
}) {
return Ok(TransferFunction::SMPTE2084);
}
if enc_params.iter().any(|p| {
let p = p.to_ascii_lowercase();
// If the user specified an SDR transfer characteristic, assume they want to encode to SDR.
p.ends_with("bt709")
|| p.ends_with("bt.709")
|| p.ends_with("bt601")
|| p.ends_with("bt.601")
|| p.contains("smpte240")
|| p.contains("smpte170")
}) {
return Ok(TransferFunction::BT1886);
}
self.transfer_function()
}
/// Calculates tiles from resolution
/// Don't convert tiles to encoder specific representation
/// Default video without tiling is 1,1

View file

@ -1088,7 +1088,9 @@ properly into a mkv file. Specify mkvmerge as the concatenation method by settin
let res = self.input.resolution()?;
let fps = self.input.frame_rate()?;
let format = self.input.pixel_format()?;
let tfc = self.input.transfer_function()?;
let tfc = self
.input
.transfer_function_params_adjusted(&self.video_params)?;
info!(
"Input: {}x{} @ {:.3} fps, {}, {}",
res.0,
@ -1138,7 +1140,9 @@ properly into a mkv file. Specify mkvmerge as the concatenation method by settin
u32::from(strength) * 100
);
let (width, height) = self.input.resolution()?;
let transfer = self.input.transfer_function()?;
let transfer = self
.input
.transfer_function_params_adjusted(&self.video_params)?;
create_film_grain_file(&table, strength, width, height, transfer)?;
} else {
debug!("Using existing grain table");
@ -1167,7 +1171,9 @@ properly into a mkv file. Specify mkvmerge as the concatenation method by settin
u32::from(strength) * 100
);
let (width, height) = self.input.resolution()?;
let transfer = self.input.transfer_function()?;
let transfer = self
.input
.transfer_function_params_adjusted(&self.video_params)?;
create_film_grain_file(&grain_table, strength, width, height, transfer)?;
grain_table
};