use anyhow::{anyhow, Result};
use bitvec_helpers::bitstream_io_writer::BitstreamIoWriter;
use super::{Frame, NALUStartCode, NAL_AUD};
pub fn clear_start_code_emulation_prevention_3_byte(data: &[u8]) -> Vec<u8> {
let len = data.len();
if len > 2 {
let mut unescaped_bytes: Vec<u8> = Vec::with_capacity(len);
unescaped_bytes.push(data[0]);
unescaped_bytes.push(data[1]);
for i in 2..len {
if !(data[i - 2] == 0 && data[i - 1] == 0 && data[i] == 3) {
unescaped_bytes.push(data[i]);
}
}
unescaped_bytes
} else {
data.to_owned()
}
}
pub fn add_start_code_emulation_prevention_3_byte(data: &mut Vec<u8>) {
let mut count = data.len();
let mut i = 0;
while i < count {
if i > 2 && data[i - 2] == 0 && data[i - 1] == 0 && data[i] <= 3 {
data.insert(i, 3);
count += 1;
}
i += 1;
}
}
pub fn aud_for_frame(frame: &Frame, start_code: Option<NALUStartCode>) -> Result<Vec<u8>> {
let pic_type: u8 = match &frame.frame_type {
2 => 0, 1 => 1, 0 => 2, _ => 7,
};
let mut data = if let Some(sc) = start_code {
sc.slice().to_vec()
} else {
Vec::new()
};
let mut writer = BitstreamIoWriter::with_capacity(24);
writer.write(false)?;
writer.write_n(&NAL_AUD, 6)?; writer.write_n(&0_u8, 6)?; writer.write_n(&1_u8, 3)?;
writer.write_n(&pic_type, 3)?;
writer.write(true)?;
writer.byte_align()?;
data.extend_from_slice(
writer
.as_slice()
.ok_or_else(|| anyhow!("Unaligned bytes"))?,
);
Ok(data)
}