use super::super::*;
use crate::av2::tiling::tile_grid_for;
impl Av2Encoder {
pub fn encode_yuv400<T: Pixel>(
&self,
planar_image: &PlanarImage<T>,
color: &Cicp,
) -> Result<Av2Frame, EncodeError> {
planar_image.validate_400()?;
let width = planar_image.width;
let height = planar_image.height;
validate_dims(width as u32, height as u32)?;
let to_plane = |s: &[T]| s.iter().map(|p| p.to_f32()).collect::<Vec<f32>>();
let (pw, ph) = (sb_align(width), sb_align(height));
let yp = pad_plane(&to_plane(&planar_image.planes[0]), width, height, pw, ph);
let config = self.config(Layout::Monochrome);
let core_frame = super::lossy::Core400Frame {
yp: &yp,
pw,
ph,
width,
height,
};
if config.lossless {
if let Some((log2c, log2r)) =
tile_grid_for(self.tune.tile_cols, self.tune.tile_rows, width, height)
{
return Ok(self.encode_400_lossless_tiled(
&yp, pw, ph, width, height, &config, color, log2c, log2r,
));
}
return Ok(self.encode_yuv400_lossless(
&yp,
pw,
ph,
width,
height,
&config,
color,
self.threads,
));
}
if let Some((log2c, log2r)) =
tile_grid_for(self.tune.tile_cols, self.tune.tile_rows, width, height)
{
return Ok(self.encode_400_tiled(&super::tiles::Tiled400Request {
yp: &yp,
pw,
ph,
width,
height,
config: &config,
color,
log2_cols: log2c,
log2_rows: log2r,
threads: self.threads,
}));
}
let multithreaded = Self::resolve_threads(self.threads) > 1;
let video = self.video_mode.load(std::sync::atomic::Ordering::Relaxed);
let mut rec = crate::av2::replay::DecisionRecord::new();
let mut enc = self.encode_400_core(
core_frame,
None,
crate::av2::replay::DecideMode::Capture(&mut rec),
);
if self.tune.cdef
&& self.base_q_idx != 0
&& let Some(dec) = enc.cdef_decided.clone()
{
let cur = crate::av2::replay::DecisionCursor::new(&rec);
enc = self.encode_400_core(
core_frame,
Some(&dec),
crate::av2::replay::DecideMode::Replay(cur),
);
} else if multithreaded && !video {
let cur = crate::av2::replay::DecisionCursor::new(&rec);
enc = self.encode_400_core(
core_frame,
None,
crate::av2::replay::DecideMode::Replay(cur),
);
}
Ok(self.finish(enc, &config, pw, ph, width, height, color))
}
pub fn encode_image_400<T: Pixel>(
&self,
img: &PlanarImage<T>,
color: &Cicp,
) -> Result<Av2Frame, EncodeError> {
img.validate_400()?;
validate_dims(img.width as u32, img.height as u32)?;
let plane = img.planes[0].to_vec();
self.encode_yuv400(
&PlanarImage {
width: img.width,
height: img.height,
bit_depth: img.bit_depth,
planes: [plane, Vec::new(), Vec::new(), Vec::new()],
},
color,
)
}
}