1+ use anyhow:: { Result , bail} ;
2+
13use self :: slice:: SliceNAL ;
24
35use super :: BitVecReader ;
@@ -42,6 +44,8 @@ pub const NAL_SEI_SUFFIX: u8 = 40;
4244pub const NAL_UNSPEC62 : u8 = 62 ;
4345pub const NAL_UNSPEC63 : u8 = 63 ;
4446
47+ pub const USER_DATA_REGISTERED_ITU_T_35 : u8 = 4 ;
48+
4549#[ derive( Default , Debug , Clone ) ]
4650pub struct NALUnit {
4751 pub start : usize ,
@@ -64,3 +68,74 @@ pub struct Frame {
6468 pub nals : Vec < NALUnit > ,
6569 pub first_slice : SliceNAL ,
6670}
71+
72+ #[ derive( Default , Debug , Clone ) ]
73+ pub struct SeiMessage {
74+ num_payload_type_ff_bytes : usize ,
75+ last_payload_type_byte : u8 ,
76+
77+ num_payload_size_ff_bytes : usize ,
78+ last_payload_size_byte : u8 ,
79+
80+ payload_type : u8 ,
81+ payload_size : usize ,
82+ }
83+
84+ impl SeiMessage {
85+ pub fn from_bytes ( data : & [ u8 ] ) -> Result < SeiMessage > {
86+ let mut reader = BitVecReader :: new ( data. to_vec ( ) ) ;
87+
88+ SeiMessage :: parse ( & mut reader)
89+ }
90+
91+ pub fn parse ( reader : & mut BitVecReader ) -> Result < SeiMessage > {
92+ // forbidden_zero_bit
93+ reader. skip_n ( 1 ) ;
94+
95+ let nal_type = reader. get_n :: < u8 > ( 6 ) ;
96+
97+ if nal_type != NAL_SEI_PREFIX {
98+ bail ! ( "NAL type {} is not SEI_PREFIX" , nal_type) ;
99+ }
100+
101+ if reader. available ( ) < 9 && matches ! ( nal_type, NAL_EOS_NUT | NAL_EOB_NUT ) {
102+ } else {
103+ reader. skip_n ( 6 ) ; // nuh_layer_id
104+ reader. skip_n ( 3 ) ; // temporal_id
105+ }
106+
107+ let mut msg;
108+
109+ loop {
110+ msg = SeiMessage :: default ( ) ;
111+
112+ msg. last_payload_type_byte = reader. get_n ( 8 ) ;
113+ while msg. last_payload_type_byte == 0xFF {
114+ msg. num_payload_type_ff_bytes += 1 ;
115+ msg. last_payload_type_byte = reader. get_n ( 8 ) ;
116+
117+ msg. payload_type += 255 ;
118+ }
119+
120+ msg. payload_type += msg. last_payload_type_byte ;
121+
122+ msg. last_payload_size_byte = reader. get_n ( 8 ) ;
123+ while msg. last_payload_size_byte == 0xFF {
124+ msg. num_payload_size_ff_bytes += 1 ;
125+ msg. last_payload_size_byte = reader. get_n ( 8 ) ;
126+
127+ msg. payload_size += 255 ;
128+ }
129+
130+ msg. payload_size += msg. last_payload_size_byte as usize ;
131+
132+ reader. skip_n ( msg. payload_size * 8 ) ;
133+
134+ if reader. available ( ) <= 8 || reader. get_n :: < u8 > ( 8 ) == 0x80 {
135+ break ;
136+ }
137+ }
138+
139+ Ok ( msg)
140+ }
141+ }
0 commit comments