use super::CodecExtra;
use super::contiguity_vp8::Vp8Contiguity;
use super::contiguity_vp9::Vp9Contiguity;
#[derive(Debug)]
pub enum Contiguity {
Vp8(Vp8Contiguity),
Vp9(Vp9Contiguity),
None,
}
impl Contiguity {
pub fn check(&mut self, next: &CodecExtra, contiguous_seq: bool) -> (bool, bool) {
match (self, next) {
(Self::Vp8(contiguity), CodecExtra::Vp8(next)) => {
contiguity.check(next, contiguous_seq)
}
(Self::Vp9(contiguity), CodecExtra::Vp9(next)) => {
contiguity.check(next, contiguous_seq)
}
(Self::Vp8(_) | Self::Vp9(_) | Self::None, _) => (true, contiguous_seq),
}
}
}
#[derive(Debug)]
pub(crate) struct FrameContiguityState {
pub(crate) last_picture_id: Option<u64>,
pub(crate) last_tl0_picture_id: Option<u64>,
}
impl FrameContiguityState {
pub(crate) fn next_frame(
&mut self,
picture_id: Option<u64>,
tl0_picture_id: Option<u64>,
layer_index: Option<u64>,
contiguous_seq: bool,
) -> (bool, bool) {
let Some(picture_id) = picture_id else {
return (true, contiguous_seq);
};
let Some(tl0_picture_id) = tl0_picture_id else {
return (true, contiguous_seq);
};
let (Some(last_tl0_picture_id), Some(last_picture_id)) =
(self.last_tl0_picture_id, self.last_picture_id)
else {
self.last_tl0_picture_id = Some(tl0_picture_id);
self.last_picture_id = Some(picture_id);
return (true, true);
};
if picture_id <= last_picture_id {
return (false, true);
}
if layer_index == Some(0) {
if tl0_picture_id == last_tl0_picture_id {
warn!(
"VP8 or VP9: 2 subsequent frames on layer zero must \
have different tl0 picture id: encoding problem?"
);
}
let emit = true;
let contiguous = tl0_picture_id == last_tl0_picture_id.wrapping_add(1);
self.last_tl0_picture_id = Some(tl0_picture_id);
self.last_picture_id = Some(picture_id);
return (emit, contiguous);
}
let emit =
tl0_picture_id == last_tl0_picture_id && picture_id == last_picture_id.wrapping_add(1);
if emit {
self.last_picture_id = Some(picture_id);
if !contiguous_seq {
debug!(
"VP8 or VP9: contiguous pictures implies contiguous seq numbers: encoding issue ?"
)
}
}
(emit, true)
}
}