h264_reader/nal/sei/
recovery_point.rs1use super::SeiMessage;
2use crate::nal::sei::HeaderType;
3use crate::rbsp::BitRead;
4use crate::rbsp::BitReaderError;
5
6#[derive(Debug)]
7pub enum RecoveryPointError {
8 ReaderError(BitReaderError),
9}
10impl From<BitReaderError> for RecoveryPointError {
11 fn from(e: BitReaderError) -> Self {
12 RecoveryPointError::ReaderError(e)
13 }
14}
15
16#[derive(Debug, PartialEq, Eq)]
21pub struct RecoveryPoint {
22 pub recovery_frame_cnt: u32,
23 pub exact_match_flag: bool,
24 pub broken_link_flag: bool,
25 pub changing_slice_group_idc: u8,
26}
27
28impl RecoveryPoint {
29 pub fn read(msg: &SeiMessage<'_>) -> Result<Self, RecoveryPointError> {
30 assert_eq!(msg.payload_type, HeaderType::RecoveryPoint);
31 let mut r = crate::rbsp::BitReader::new(msg.payload);
32 let recovery_frame_cnt = r.read_ue("recovery_frame_cnt")?;
33 let exact_match_flag = r.read_bit("exact_match_flag")?;
34 let broken_link_flag = r.read_bit("broken_link_flag")?;
35 let changing_slice_group_idc = r.read::<2, u8>("changing_slice_group_idc")?;
36 r.finish_sei_payload()?;
37 Ok(RecoveryPoint {
38 recovery_frame_cnt,
39 exact_match_flag,
40 broken_link_flag,
41 changing_slice_group_idc,
42 })
43 }
44}
45
46#[cfg(test)]
47mod test {
48 use super::*;
49
50 #[test]
51 fn parse() {
52 let msg = SeiMessage {
59 payload_type: HeaderType::RecoveryPoint,
60 payload: &[0xC4],
61 };
62 let rp = RecoveryPoint::read(&msg).unwrap();
63 assert_eq!(rp.recovery_frame_cnt, 0);
64 assert!(rp.exact_match_flag);
65 assert!(!rp.broken_link_flag);
66 assert_eq!(rp.changing_slice_group_idc, 0);
67 }
68
69 #[test]
70 fn parse_nonzero_frame_cnt() {
71 let msg = SeiMessage {
78 payload_type: HeaderType::RecoveryPoint,
79 payload: &[0x32, 0xC0],
80 };
81 let rp = RecoveryPoint::read(&msg).unwrap();
82 assert_eq!(rp.recovery_frame_cnt, 5);
83 assert!(!rp.exact_match_flag);
84 assert!(rp.broken_link_flag);
85 assert_eq!(rp.changing_slice_group_idc, 1);
86 }
87}