mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 21:11:00 +00:00
dav1d: Set colorimetry parameters on src pad caps
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1514>
This commit is contained in:
parent
61c9cbdc8f
commit
2341ee6935
3 changed files with 161 additions and 7 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -301,6 +301,20 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "av-data"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d75b98a3525d00f920df9a2d44cc99b9cc5b7dc70d7fbb612cd755270dbe6552"
|
||||||
|
dependencies = [
|
||||||
|
"byte-slice-cast",
|
||||||
|
"bytes",
|
||||||
|
"num-derive",
|
||||||
|
"num-rational",
|
||||||
|
"num-traits",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "av1-grain"
|
name = "av1-grain"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -1450,12 +1464,14 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dav1d"
|
name = "dav1d"
|
||||||
version = "0.10.2"
|
version = "0.10.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7eb1fa9954b7ae85ff0d43ef6d186d1b3469d4aa1574845d1938bef05377030"
|
checksum = "0d4b54a40baf633a71c6f0fb49494a7e4ee7bc26f3e727212b6cb915aa1ea1e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"av-data",
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"dav1d-sys",
|
"dav1d-sys",
|
||||||
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -6187,6 +6203,12 @@ version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c0cdea5a20a06e7c57f627094e7b1618e5665592cd88f2d45fa4014e348db58"
|
checksum = "6c0cdea5a20a06e7c57f627094e7b1618e5665592cd88f2d45fa4014e348db58"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strength_reduce"
|
name = "strength_reduce"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
|
|
@ -9,10 +9,10 @@ license = "MIT OR Apache-2.0"
|
||||||
description = "GStreamer dav1d AV1 decoder Plugin"
|
description = "GStreamer dav1d AV1 decoder Plugin"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dav1d = "0.10"
|
dav1d = "0.10.3"
|
||||||
gst.workspace = true
|
gst = { workspace = true, features = ["v1_18"] }
|
||||||
gst-base.workspace = true
|
gst-base = { workspace = true, features = ["v1_18"] }
|
||||||
gst-video.workspace = true
|
gst-video = { workspace = true, features = ["v1_18"] }
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
once_cell.workspace = true
|
once_cell.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,101 @@ impl Dav1dDec {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn colorimetry_from_dav1d_picture(
|
||||||
|
&self,
|
||||||
|
pic: &dav1d::Picture,
|
||||||
|
) -> Option<gst_video::VideoColorimetry> {
|
||||||
|
use dav1d::pixel;
|
||||||
|
|
||||||
|
let range = match pic.color_range() {
|
||||||
|
pixel::YUVRange::Limited => gst_video::VideoColorRange::Range16_235,
|
||||||
|
pixel::YUVRange::Full => gst_video::VideoColorRange::Range0_255,
|
||||||
|
};
|
||||||
|
|
||||||
|
let matrix = match pic.matrix_coefficients() {
|
||||||
|
pixel::MatrixCoefficients::Identity => gst_video::VideoColorMatrix::Rgb,
|
||||||
|
pixel::MatrixCoefficients::BT709 => gst_video::VideoColorMatrix::Bt709,
|
||||||
|
pixel::MatrixCoefficients::Unspecified => gst_video::VideoColorMatrix::Unknown,
|
||||||
|
pixel::MatrixCoefficients::BT470M => gst_video::VideoColorMatrix::Fcc,
|
||||||
|
pixel::MatrixCoefficients::BT470BG => gst_video::VideoColorMatrix::Bt601,
|
||||||
|
pixel::MatrixCoefficients::ST240M => gst_video::VideoColorMatrix::Smpte240m,
|
||||||
|
pixel::MatrixCoefficients::BT2020NonConstantLuminance => {
|
||||||
|
gst_video::VideoColorMatrix::Bt2020
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
gst::warning!(CAT, imp: self, "Unsupported dav1d colorimetry matrix coefficients");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let transfer = match pic.transfer_characteristic() {
|
||||||
|
pixel::TransferCharacteristic::BT1886 => gst_video::VideoTransferFunction::Bt709,
|
||||||
|
pixel::TransferCharacteristic::Unspecified => gst_video::VideoTransferFunction::Unknown,
|
||||||
|
pixel::TransferCharacteristic::BT470M => gst_video::VideoTransferFunction::Bt709,
|
||||||
|
pixel::TransferCharacteristic::BT470BG => gst_video::VideoTransferFunction::Gamma28,
|
||||||
|
pixel::TransferCharacteristic::ST170M => gst_video::VideoTransferFunction::Bt601,
|
||||||
|
pixel::TransferCharacteristic::ST240M => gst_video::VideoTransferFunction::Smpte240m,
|
||||||
|
pixel::TransferCharacteristic::Linear => gst_video::VideoTransferFunction::Gamma10,
|
||||||
|
pixel::TransferCharacteristic::Logarithmic100 => {
|
||||||
|
gst_video::VideoTransferFunction::Log100
|
||||||
|
}
|
||||||
|
pixel::TransferCharacteristic::Logarithmic316 => {
|
||||||
|
gst_video::VideoTransferFunction::Log316
|
||||||
|
}
|
||||||
|
pixel::TransferCharacteristic::SRGB => gst_video::VideoTransferFunction::Srgb,
|
||||||
|
pixel::TransferCharacteristic::BT2020Ten => gst_video::VideoTransferFunction::Bt202010,
|
||||||
|
pixel::TransferCharacteristic::BT2020Twelve => {
|
||||||
|
gst_video::VideoTransferFunction::Bt202012
|
||||||
|
}
|
||||||
|
pixel::TransferCharacteristic::PerceptualQuantizer => {
|
||||||
|
gst_video::VideoTransferFunction::Smpte2084
|
||||||
|
}
|
||||||
|
pixel::TransferCharacteristic::HybridLogGamma => {
|
||||||
|
gst_video::VideoTransferFunction::AribStdB67
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
gst::warning!(CAT, imp: self, "Unsupported dav1d colorimetry transfer function");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let primaries = match pic.color_primaries() {
|
||||||
|
pixel::ColorPrimaries::BT709 => gst_video::VideoColorPrimaries::Bt709,
|
||||||
|
pixel::ColorPrimaries::Unspecified => gst_video::VideoColorPrimaries::Unknown,
|
||||||
|
pixel::ColorPrimaries::BT470M => gst_video::VideoColorPrimaries::Bt470m,
|
||||||
|
pixel::ColorPrimaries::BT470BG => gst_video::VideoColorPrimaries::Bt470bg,
|
||||||
|
pixel::ColorPrimaries::ST240M => gst_video::VideoColorPrimaries::Smpte240m,
|
||||||
|
pixel::ColorPrimaries::Film => gst_video::VideoColorPrimaries::Film,
|
||||||
|
pixel::ColorPrimaries::BT2020 => gst_video::VideoColorPrimaries::Bt2020,
|
||||||
|
pixel::ColorPrimaries::ST428 => gst_video::VideoColorPrimaries::Smptest428,
|
||||||
|
pixel::ColorPrimaries::P3DCI => gst_video::VideoColorPrimaries::Smpterp431,
|
||||||
|
pixel::ColorPrimaries::P3Display => gst_video::VideoColorPrimaries::Smpteeg432,
|
||||||
|
pixel::ColorPrimaries::Tech3213 => gst_video::VideoColorPrimaries::Ebu3213,
|
||||||
|
_ => {
|
||||||
|
gst::warning!(CAT, imp: self, "Unsupported dav1d color primaries");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(gst_video::VideoColorimetry::new(
|
||||||
|
range, matrix, transfer, primaries,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chroma_site_from_dav1d_picture(
|
||||||
|
&self,
|
||||||
|
pic: &dav1d::Picture,
|
||||||
|
) -> Option<gst_video::VideoChromaSite> {
|
||||||
|
use dav1d::pixel;
|
||||||
|
match pic.pixel_layout() {
|
||||||
|
dav1d::PixelLayout::I420 | dav1d::PixelLayout::I422 => match pic.chroma_location() {
|
||||||
|
pixel::ChromaLocation::Center => Some(gst_video::VideoChromaSite::JPEG),
|
||||||
|
pixel::ChromaLocation::Left => Some(gst_video::VideoChromaSite::MPEG2),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_resolution_change<'s>(
|
fn handle_resolution_change<'s>(
|
||||||
&'s self,
|
&'s self,
|
||||||
mut state_guard: MutexGuard<'s, Option<State>>,
|
mut state_guard: MutexGuard<'s, Option<State>>,
|
||||||
|
@ -155,11 +250,48 @@ impl Dav1dDec {
|
||||||
);
|
);
|
||||||
|
|
||||||
let input_state = state.input_state.clone();
|
let input_state = state.input_state.clone();
|
||||||
|
let input_info = input_state.info();
|
||||||
|
let input_caps = input_state.caps().ok_or(gst::FlowError::NotNegotiated)?;
|
||||||
|
let input_structure = input_caps
|
||||||
|
.structure(0)
|
||||||
|
.ok_or(gst::FlowError::NotNegotiated)?;
|
||||||
|
let input_colorimetry = input_info.colorimetry();
|
||||||
|
|
||||||
drop(state_guard);
|
drop(state_guard);
|
||||||
|
|
||||||
let instance = self.obj();
|
let instance = self.obj();
|
||||||
let output_state =
|
let mut output_state =
|
||||||
instance.set_output_state(format, pic.width(), pic.height(), Some(&input_state))?;
|
instance.set_output_state(format, pic.width(), pic.height(), Some(&input_state))?;
|
||||||
|
let mut info_builder = gst_video::VideoInfo::builder(format, pic.width(), pic.height());
|
||||||
|
let mut update_output_state = false;
|
||||||
|
|
||||||
|
let colorimetry = self.colorimetry_from_dav1d_picture(pic);
|
||||||
|
if !input_structure.has_field("colorimetry")
|
||||||
|
|| input_colorimetry.range() == gst_video::VideoColorRange::Unknown
|
||||||
|
|| input_colorimetry.matrix() == gst_video::VideoColorMatrix::Unknown
|
||||||
|
|| input_colorimetry.transfer() == gst_video::VideoTransferFunction::Unknown
|
||||||
|
|| input_colorimetry.primaries() == gst_video::VideoColorPrimaries::Unknown
|
||||||
|
{
|
||||||
|
if let Some(colorimetry) = colorimetry.as_ref() {
|
||||||
|
info_builder = info_builder.colorimetry(colorimetry);
|
||||||
|
update_output_state = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !input_structure.has_field("chroma-site") {
|
||||||
|
if let Some(chroma_site) = self.chroma_site_from_dav1d_picture(pic) {
|
||||||
|
info_builder = info_builder.chroma_site(chroma_site);
|
||||||
|
update_output_state = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if update_output_state {
|
||||||
|
let info = info_builder
|
||||||
|
.build()
|
||||||
|
.map_err(|_| gst::FlowError::NotNegotiated)?;
|
||||||
|
output_state.set_info(info);
|
||||||
|
}
|
||||||
|
|
||||||
instance.negotiate(output_state)?;
|
instance.negotiate(output_state)?;
|
||||||
let out_state = instance.output_state().unwrap();
|
let out_state = instance.output_state().unwrap();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue