media_codec/
packet.rs

1use std::{
2    borrow::Cow,
3    io::{self, Read, Write},
4};
5
6use bitflags::bitflags;
7use media_core::{error::Error, invalid_param_error, Result};
8use num_rational::Rational64;
9
10bitflags! {
11    #[repr(transparent)]
12    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
13    pub struct PacketFlags: u32 {
14        const Key = 1;
15        const Corrupt = 2;
16    }
17}
18
19#[derive(Clone)]
20pub struct Packet<'a> {
21    pub pts: Option<i64>,
22    pub dts: Option<i64>,
23    pub duration: Option<i64>,
24    pub time_base: Option<Rational64>,
25    pub flags: PacketFlags,
26    pub pos: Option<usize>,
27    pub stream_index: Option<usize>,
28    data: Cow<'a, [u8]>,
29}
30
31impl<'a> Packet<'a> {
32    fn from_data<T>(data: T) -> Self
33    where
34        T: Into<Cow<'a, [u8]>>,
35    {
36        Self {
37            pts: None,
38            dts: None,
39            duration: None,
40            time_base: None,
41            flags: PacketFlags::empty(),
42            pos: None,
43            stream_index: None,
44            data: data.into(),
45        }
46    }
47
48    pub fn new(size: usize) -> Self {
49        Self::from_data(vec![0; size])
50    }
51
52    pub fn with_capacity(capacity: usize) -> Self {
53        Self::from_data(Vec::with_capacity(capacity))
54    }
55
56    pub fn from_slice(data: &'a [u8]) -> Self {
57        Self::from_data(data)
58    }
59
60    pub fn into_owned(self) -> Packet<'static> {
61        Packet {
62            pts: self.pts,
63            dts: self.dts,
64            duration: self.duration,
65            time_base: self.time_base,
66            flags: self.flags,
67            pos: self.pos,
68            stream_index: self.stream_index,
69            data: Cow::Owned(self.data.into_owned()),
70        }
71    }
72
73    pub fn data(&self) -> &[u8] {
74        &self.data
75    }
76
77    pub fn data_mut(&mut self) -> Option<&mut [u8]> {
78        match &mut self.data {
79            Cow::Borrowed(_) => None,
80            Cow::Owned(ref mut vec) => Some(vec),
81        }
82    }
83
84    pub fn truncate(&mut self, len: usize) -> Result<()> {
85        let current_len = self.data.len();
86        if len > current_len {
87            return Err(invalid_param_error!(len));
88        }
89
90        match &mut self.data {
91            Cow::Owned(ref mut vec) => vec.truncate(len),
92            Cow::Borrowed(slice) => {
93                self.data = Cow::Borrowed(&slice[..len]);
94            }
95        }
96        Ok(())
97    }
98}
99
100pub trait ReadPacket: Read {
101    fn read_packet(&mut self, size: usize) -> io::Result<Packet<'_>> {
102        let mut packet = Packet::new(size);
103
104        if let Cow::Owned(ref mut vec) = packet.data {
105            self.read_exact(vec)?;
106        } else {
107            // Packet::new always creates an owned packet
108            unreachable!()
109        }
110
111        Ok(packet)
112    }
113}
114
115pub trait WritePacket: Write {
116    fn write_packet(&mut self, packet: &Packet) -> io::Result<()> {
117        self.write_all(&packet.data)
118    }
119}
120
121impl<T: Read + ?Sized> ReadPacket for T {}
122impl<T: Write + ?Sized> WritePacket for T {}