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 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 {}