1use anyhow::Result;
2use nom::{IResult, bytes::complete::take_until};
3
4use bitvec_helpers::bitstream_io_reader::BsIoVecReader;
5
6pub mod hevc;
7pub mod utils;
8
9#[cfg(feature = "hevc_io")]
10pub mod io;
11
12use hevc::*;
13use pps::PPSNAL;
14use slice::SliceNAL;
15use sps::SPSNAL;
16use vps::VPSNAL;
17
18use utils::clear_start_code_emulation_prevention_3_byte;
19
20const MAX_PARSE_SIZE: usize = 2048;
22
23const HEADER_LEN_3: usize = 3;
24const HEADER_LEN_4: usize = 4;
25const NAL_START_CODE_3: &[u8] = &[0, 0, 1];
26const NAL_START_CODE_4: &[u8] = &[0, 0, 0, 1];
27
28#[derive(Debug, Default, Copy, Clone)]
29pub enum NALUStartCode {
30 #[default]
31 Length3,
32 Length4,
33}
34
35#[derive(Default)]
36pub struct HevcParser {
37 reader: BsIoVecReader,
38 pub nalu_start_code: NALUStartCode,
39
40 nals: Vec<NALUnit>,
41 vps: Vec<VPSNAL>,
42 sps: Vec<SPSNAL>,
43 pps: Vec<PPSNAL>,
44 ordered_frames: Vec<Frame>,
45 frames: Vec<Frame>,
46
47 poc: u64,
48 poc_tid0: u64,
49
50 current_frame: Frame,
51 decoded_index: u64,
52 presentation_index: u64,
53}
54
55impl HevcParser {
56 fn take_until_nal<'a>(tag: &[u8], data: &'a [u8]) -> IResult<&'a [u8], &'a [u8]> {
57 take_until(tag)(data)
58 }
59
60 pub fn with_nalu_start_code(start_code: NALUStartCode) -> HevcParser {
61 HevcParser {
62 nalu_start_code: start_code,
63 ..Default::default()
64 }
65 }
66
67 pub fn get_offsets(&mut self, data: &[u8], offsets: &mut Vec<usize>) {
68 offsets.clear();
69
70 let mut consumed = 0;
71
72 let nal_start_tag = self.nalu_start_code.slice();
73
74 loop {
75 match Self::take_until_nal(nal_start_tag, &data[consumed..]) {
76 Ok(nal) => {
77 consumed += nal.1.len();
79
80 offsets.push(consumed);
81
82 consumed += self.nalu_start_code.size();
84 }
85 _ => return,
86 }
87 }
88 }
89
90 pub fn split_nals(
91 &mut self,
92 data: &[u8],
93 offsets: &[usize],
94 last: usize,
95 parse_nals: bool,
96 ) -> Result<Vec<NALUnit>> {
97 let count = offsets.len();
98
99 let mut nals = Vec::with_capacity(count);
100
101 for (index, offset) in offsets.iter().enumerate() {
102 let size = if offset == &last {
103 data.len() - offset
104 } else {
105 let size = if index == count - 1 {
106 last - offset
107 } else {
108 offsets[index + 1] - offset
109 };
110
111 match &data[offset + size - 1..offset + size + 3] {
112 [0, 0, 0, 1] => size - 1,
113 _ => size,
114 }
115 };
116
117 let nal = self.parse_nal(data, *offset, size, parse_nals)?;
118
119 nals.push(nal);
120 }
121
122 Ok(nals)
123 }
124
125 fn parse_nal(
126 &mut self,
127 data: &[u8],
128 offset: usize,
129 size: usize,
130 parse_nal: bool,
131 ) -> Result<NALUnit> {
132 let mut nal = NALUnit::default();
133
134 let pos = offset + HEADER_LEN_3;
137 let end = offset + size;
138
139 let parsing_end = if size > MAX_PARSE_SIZE {
140 offset + MAX_PARSE_SIZE
141 } else {
142 end
143 };
144
145 nal.start = pos;
146 nal.end = end;
147 nal.decoded_frame_index = self.decoded_index;
148
149 nal.start_code = if offset > 0 {
150 if data[offset - 1] == 0 {
153 NALUStartCode::Length4
154 } else {
155 NALUStartCode::Length3
156 }
157 } else {
158 NALUStartCode::Length3
159 };
160
161 #[allow(deprecated)]
162 {
163 nal.start_code_len = nal.start_code.size() as u8;
164 }
165
166 let buf = &data[pos..parsing_end];
167 self.handle_nal_without_start_code(buf, nal, parse_nal)
168 }
169
170 fn parse_nal_header(&mut self, nal: &mut NALUnit) -> Result<()> {
171 self.reader.read_bit()?;
173
174 nal.nal_type = self.reader.read::<6, u8>()?;
175
176 if self.reader.available()? < 9 && matches!(nal.nal_type, NAL_EOS_NUT | NAL_EOB_NUT) {
177 } else {
178 nal.nuh_layer_id = self.reader.read::<6, u8>()?;
179 nal.temporal_id = self.reader.read::<3, u8>()? - 1;
180 }
181
182 Ok(())
183 }
184
185 fn handle_nal_without_start_code(
186 &mut self,
187 data: &[u8],
188 mut nal: NALUnit,
189 parse_nal: bool,
190 ) -> Result<NALUnit> {
191 if parse_nal {
192 let bytes = clear_start_code_emulation_prevention_3_byte(data);
193 self.reader.replace_vec(bytes);
194
195 self.parse_nal_header(&mut nal)?;
196 } else {
197 nal.nal_type = data[0] >> 1;
198 }
199
200 if nal.nuh_layer_id > 0 {
201 return Ok(nal);
202 }
203
204 if parse_nal {
205 self.parse_nal_internal(&mut nal)?;
206 self.nals.push(nal.clone());
207 }
208
209 Ok(nal)
210 }
211
212 fn parse_nal_internal(&mut self, nal: &mut NALUnit) -> Result<()> {
213 match nal.nal_type {
214 NAL_VPS => self.parse_vps()?,
215 NAL_SPS => self.parse_sps()?,
216 NAL_PPS => self.parse_pps()?,
217
218 NAL_TRAIL_R | NAL_TRAIL_N | NAL_TSA_N | NAL_TSA_R | NAL_STSA_N | NAL_STSA_R
219 | NAL_BLA_W_LP | NAL_BLA_W_RADL | NAL_BLA_N_LP | NAL_IDR_W_RADL | NAL_IDR_N_LP
220 | NAL_CRA_NUT | NAL_RADL_N | NAL_RADL_R | NAL_RASL_N | NAL_RASL_R => {
221 self.parse_slice(nal)?;
222
223 self.current_frame.nals.push(nal.clone());
224 }
225 NAL_SEI_SUFFIX | NAL_UNSPEC62 | NAL_UNSPEC63 | NAL_EOS_NUT | NAL_EOB_NUT
226 | NAL_FD_NUT => {
227 self.current_frame.nals.push(nal.clone());
230 }
231 _ => {
232 self.add_current_frame();
233
234 nal.decoded_frame_index = self.decoded_index;
235 self.current_frame.nals.push(nal.clone());
236 }
237 };
238
239 match nal.nal_type {
241 NAL_VPS | NAL_SPS | NAL_PPS => {
242 self.add_current_frame();
243
244 nal.decoded_frame_index = self.decoded_index;
245 self.current_frame.nals.push(nal.clone());
246 }
247 _ => (),
248 };
249
250 Ok(())
251 }
252
253 fn parse_vps(&mut self) -> Result<()> {
254 let vps = VPSNAL::parse(&mut self.reader)?;
255
256 self.remove_vps(&vps);
257
258 self.vps.push(vps);
259
260 Ok(())
261 }
262
263 fn parse_sps(&mut self) -> Result<()> {
264 let sps = SPSNAL::parse(&mut self.reader)?;
265 self.remove_sps(&sps);
266
267 self.sps.push(sps);
268
269 Ok(())
270 }
271
272 fn parse_pps(&mut self) -> Result<()> {
273 let pps = PPSNAL::parse(&mut self.reader)?;
274
275 self.remove_pps(&pps);
276
277 self.pps.push(pps);
278
279 Ok(())
280 }
281
282 fn parse_slice(&mut self, nal: &mut NALUnit) -> Result<()> {
283 let slice = SliceNAL::parse(
284 &mut self.reader,
285 &self.sps,
286 &self.pps,
287 nal,
288 &mut self.poc_tid0,
289 &mut self.poc,
290 )?;
291
292 if self.current_frame.first_slice.first_slice_in_pic_flag && slice.first_slice_in_pic_flag {
294 nal.decoded_frame_index = self.decoded_index + 1;
295 self.add_current_frame();
296 }
297
298 if slice.key_frame {
299 self.reorder_frames();
300 }
301
302 if slice.first_slice_in_pic_flag {
303 self.current_frame.first_slice = slice;
304
305 self.current_frame.decoded_number = self.decoded_index;
306 }
307
308 Ok(())
309 }
310
311 fn remove_vps(&mut self, vps: &VPSNAL) {
312 let id = vps.vps_id as usize;
313
314 if let Some(existing_vps) = self.vps.get(id) {
315 if existing_vps == vps {
316 self.vps.remove(id);
317
318 let sps_to_remove: Vec<SPSNAL> = self
319 .sps
320 .clone()
321 .into_iter()
322 .filter(|sps| sps.vps_id == vps.vps_id)
323 .collect();
324
325 sps_to_remove.iter().for_each(|sps| self.remove_sps(sps));
326 }
327 }
328 }
329
330 fn remove_sps(&mut self, sps: &SPSNAL) {
331 let id = sps.sps_id as usize;
332
333 if let Some(existing_sps) = self.sps.get(id) {
334 if existing_sps == sps {
335 self.sps.remove(id);
336
337 self.pps.retain(|pps| pps.sps_id != sps.sps_id);
339 }
340 }
341 }
342
343 fn remove_pps(&mut self, pps: &PPSNAL) {
344 if let Some(existing_pps) = self.pps.get(pps.pps_id as usize) {
346 if existing_pps == pps {
347 self.pps.remove(pps.pps_id as usize);
348 }
349 }
350 }
351
352 fn add_current_frame(&mut self) {
354 if self.current_frame.first_slice.first_slice_in_pic_flag {
355 self.decoded_index += 1;
356
357 self.current_frame.presentation_number =
358 self.current_frame.first_slice.output_picture_number;
359
360 self.current_frame.frame_type = self.current_frame.first_slice.slice_type;
361
362 self.frames.push(self.current_frame.clone());
363
364 self.current_frame = Frame::default();
365 }
366 }
367
368 fn reorder_frames(&mut self) {
369 let mut offset = self.presentation_index;
370
371 self.frames.sort_by_key(|f| f.presentation_number);
372 self.frames.iter_mut().for_each(|f| {
373 f.presentation_number = offset;
374 offset += 1;
375 });
376
377 self.presentation_index = offset;
378 self.ordered_frames.extend_from_slice(&self.frames);
379 self.frames.clear();
380 }
381
382 pub fn display(&self) {
383 println!("{} frames", &self.ordered_frames.len());
384 for frame in &self.ordered_frames {
385 let pict_type = match frame.frame_type {
386 2 => "I",
387 1 => "P",
388 0 => "B",
389 _ => "",
390 };
391
392 println!(
393 "{} display order {} poc {} pos {}",
394 pict_type,
395 frame.presentation_number,
396 frame.first_slice.output_picture_number,
397 frame.decoded_number
398 );
399 }
400 }
401
402 pub fn finish(&mut self) {
403 self.add_current_frame();
404 self.reorder_frames();
405 }
406
407 pub fn processed_frames(&self) -> &Vec<Frame> {
410 &self.frames
411 }
412
413 pub fn ordered_frames(&self) -> &Vec<Frame> {
414 &self.ordered_frames
415 }
416
417 pub fn get_nals(&self) -> &Vec<NALUnit> {
418 &self.nals
419 }
420}
421
422impl NALUStartCode {
423 pub const fn slice(&self) -> &[u8] {
424 match self {
425 NALUStartCode::Length3 => NAL_START_CODE_3,
426 NALUStartCode::Length4 => NAL_START_CODE_4,
427 }
428 }
429
430 pub const fn size(&self) -> usize {
431 match self {
432 NALUStartCode::Length3 => HEADER_LEN_3,
433 NALUStartCode::Length4 => HEADER_LEN_4,
434 }
435 }
436}