mpeg2ts 0.6.0

MPEG2-TS decoding/encoding library
Documentation
use crate::crc::Crc32;
use crate::ts::TsPacket;
use crate::{Error, Result};
use std::io::{self, Read, Write};

#[track_caller]
pub fn consume_stuffing_bytes<R: Read>(mut reader: R) -> Result<()> {
    let mut buf = [0];
    while 1 == reader.read(&mut buf)? {
        if buf[0] != 0xFF {
            return Err(Error::invalid_input("Expected stuffing byte 0xFF"));
        }
    }
    Ok(())
}

#[track_caller]
pub fn write_stuffing_bytes<W: Write>(mut writer: W, size: usize) -> Result<()> {
    let buf = [0xFF; TsPacket::SIZE];
    writer.write_all(&buf[..size])?;
    Ok(())
}

#[derive(Debug)]
pub struct WithCrc32<T> {
    stream: T,
    crc32: Crc32,
}
impl<T> WithCrc32<T> {
    pub fn new(stream: T) -> Self {
        WithCrc32 {
            stream,
            crc32: Crc32::new(),
        }
    }
    pub fn crc32(&self) -> u32 {
        self.crc32.value()
    }
}
impl<T: Read> Read for WithCrc32<T> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let size = self.stream.read(buf)?;
        self.crc32.update(&buf[..size]);
        Ok(size)
    }
}
impl<T: Write> Write for WithCrc32<T> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let size = self.stream.write(buf)?;
        self.crc32.update(&buf[..size]);
        Ok(size)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.stream.flush()
    }
}

pub trait WriteBytesExt {
    fn write_u8(&mut self, n: u8) -> std::io::Result<()>;
    fn write_u16(&mut self, n: u16) -> std::io::Result<()>;
    fn write_u32(&mut self, n: u32) -> std::io::Result<()>;
    fn write_uint<const SIZE: usize>(&mut self, n: u64) -> std::io::Result<()>;
    fn write_i8(&mut self, n: i8) -> std::io::Result<()>;
}

impl<W: Write> WriteBytesExt for W {
    fn write_u8(&mut self, n: u8) -> std::io::Result<()> {
        self.write_all(&[n])
    }
    fn write_u16(&mut self, n: u16) -> std::io::Result<()> {
        self.write_all(&n.to_be_bytes())
    }
    fn write_u32(&mut self, n: u32) -> std::io::Result<()> {
        self.write_all(&n.to_be_bytes())
    }
    fn write_uint<const SIZE: usize>(&mut self, n: u64) -> std::io::Result<()> {
        let bytes = n.to_be_bytes();
        self.write_all(&bytes[8 - SIZE..])
    }
    fn write_i8(&mut self, n: i8) -> std::io::Result<()> {
        self.write_all(&[n as u8])
    }
}

pub trait ReadBytesExt {
    fn read_u8(&mut self) -> std::io::Result<u8>;
    fn read_u16(&mut self) -> std::io::Result<u16>;
    fn read_u32(&mut self) -> std::io::Result<u32>;
    fn read_uint<const SIZE: usize>(&mut self) -> std::io::Result<u64>;
    fn read_i8(&mut self) -> std::io::Result<i8>;
}

impl<R: Read> ReadBytesExt for R {
    fn read_u8(&mut self) -> std::io::Result<u8> {
        let mut buf = [0; 1];
        Read::read_exact(self, &mut buf)?;
        Ok(buf[0])
    }
    fn read_u16(&mut self) -> std::io::Result<u16> {
        let mut buf = [0; 2];
        Read::read_exact(self, &mut buf)?;
        Ok(u16::from_be_bytes(buf))
    }
    fn read_u32(&mut self) -> std::io::Result<u32> {
        let mut buf = [0; 4];
        Read::read_exact(self, &mut buf)?;
        Ok(u32::from_be_bytes(buf))
    }
    fn read_uint<const SIZE: usize>(&mut self) -> std::io::Result<u64> {
        let mut buf = [0; 8];
        Read::read_exact(self, &mut buf[8 - SIZE..])?;
        Ok(u64::from_be_bytes(buf))
    }
    fn read_i8(&mut self) -> std::io::Result<i8> {
        let mut buf = [0; 1];
        Read::read_exact(self, &mut buf)?;
        Ok(buf[0] as i8)
    }
}