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