use crate::*;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cslg {
pub composition_to_dts_shift: i64,
pub least_decode_to_display_shift: i64,
pub greatest_decode_to_display_delta: i64,
pub composition_start_time: i64,
pub composition_end_time: i64,
}
ext! {
name: Cslg,
versions: [0, 1],
flags: {}
}
impl AtomExt for Cslg {
type Ext = CslgExt;
const KIND_EXT: FourCC = FourCC::new(b"cslg");
fn decode_body_ext<B: Buf>(buf: &mut B, ext: CslgExt) -> Result<Self> {
if ext.version == CslgVersion::V0 {
Ok(Cslg {
composition_to_dts_shift: i32::decode(buf)?.into(),
least_decode_to_display_shift: i32::decode(buf)?.into(),
greatest_decode_to_display_delta: i32::decode(buf)?.into(),
composition_start_time: i32::decode(buf)?.into(),
composition_end_time: i32::decode(buf)?.into(),
})
} else {
Ok(Cslg {
composition_to_dts_shift: i64::decode(buf)?,
least_decode_to_display_shift: i64::decode(buf)?,
greatest_decode_to_display_delta: i64::decode(buf)?,
composition_start_time: i64::decode(buf)?,
composition_end_time: i64::decode(buf)?,
})
}
}
fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<CslgExt> {
match (
i32::try_from(self.composition_to_dts_shift),
i32::try_from(self.least_decode_to_display_shift),
i32::try_from(self.greatest_decode_to_display_delta),
i32::try_from(self.composition_start_time),
i32::try_from(self.composition_end_time),
) {
(
Ok(composition_to_dts_shift),
Ok(least_decode_to_display_shift),
Ok(greatest_decode_to_display_delta),
Ok(composition_start_time),
Ok(composition_end_time),
) => {
composition_to_dts_shift.encode(buf)?;
least_decode_to_display_shift.encode(buf)?;
greatest_decode_to_display_delta.encode(buf)?;
composition_start_time.encode(buf)?;
composition_end_time.encode(buf)?;
Ok(CslgExt {
version: CslgVersion::V0,
})
}
_ => {
self.composition_to_dts_shift.encode(buf)?;
self.least_decode_to_display_shift.encode(buf)?;
self.greatest_decode_to_display_delta.encode(buf)?;
self.composition_start_time.encode(buf)?;
self.composition_end_time.encode(buf)?;
Ok(CslgExt {
version: CslgVersion::V1,
})
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const ENCODED_CSLG_V0: &[u8] = &[
0x00, 0x00, 0x00, 0x20, 0x63, 0x73, 0x6c, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x13, 0x88,
];
const ENCODED_CSLG_V1: &[u8] = &[
0x00, 0x00, 0x00, 0x34, b'c', b's', b'l', b'g', 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
];
const ENCODED_CSLG_V1_VARIANT: &[u8] = &[
0x00, 0x00, 0x00, 0x34, b'c', b's', b'l', b'g', 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
];
#[test]
fn test_cslg_v0() {
let buf: &mut std::io::Cursor<&&[u8]> = &mut std::io::Cursor::new(&ENCODED_CSLG_V0);
let cslg = Cslg::decode(buf).expect("failed to decode cslg");
assert_eq!(
cslg,
Cslg {
composition_to_dts_shift: 8,
least_decode_to_display_shift: -8,
greatest_decode_to_display_delta: 8,
composition_start_time: 0,
composition_end_time: 5000
},
);
let mut buf = Vec::new();
cslg.encode(&mut buf).unwrap();
assert_eq!(buf.as_slice(), ENCODED_CSLG_V0);
}
#[test]
fn test_cslg_v1_encode() {
let cslg = Cslg {
composition_to_dts_shift: 2147483648,
least_decode_to_display_shift: -2147483649,
greatest_decode_to_display_delta: 8,
composition_start_time: i64::MIN,
composition_end_time: i64::MAX,
};
let mut buf = Vec::new();
cslg.encode(&mut buf).unwrap();
assert_eq!(buf.as_slice(), ENCODED_CSLG_V1);
}
#[test]
fn test_cslg_v1_decode() {
let buf: &mut std::io::Cursor<&&[u8]> = &mut std::io::Cursor::new(&ENCODED_CSLG_V1);
let cslg = Cslg::decode(buf).expect("failed to decode cslg");
assert_eq!(
cslg,
Cslg {
composition_to_dts_shift: 2147483648,
least_decode_to_display_shift: -2147483649,
greatest_decode_to_display_delta: 8,
composition_start_time: i64::MIN,
composition_end_time: i64::MAX,
},
);
}
#[test]
fn test_cslg_v1_encode_variant() {
let cslg = Cslg {
composition_to_dts_shift: 2147483647,
least_decode_to_display_shift: -2147483649,
greatest_decode_to_display_delta: 8,
composition_start_time: i64::MIN,
composition_end_time: i64::MAX,
};
let mut buf = Vec::new();
cslg.encode(&mut buf).unwrap();
assert_eq!(buf.as_slice(), ENCODED_CSLG_V1_VARIANT);
}
}