playa_ffmpeg/codec/packet/
packet.rs

1use std::{marker::PhantomData, mem, slice};
2
3use super::{Borrow, Flags, Mut, Ref, SideData};
4use crate::{Error, Rational, ffi::*, format};
5use libc::c_int;
6
7pub struct Packet(AVPacket);
8
9unsafe impl Send for Packet {}
10unsafe impl Sync for Packet {}
11
12impl Packet {
13    #[inline(always)]
14    pub unsafe fn is_empty(&self) -> bool {
15        self.0.size == 0
16    }
17}
18
19impl Packet {
20    #[inline]
21    pub fn empty() -> Self {
22        unsafe {
23            let mut pkt: AVPacket = mem::zeroed();
24
25            av_init_packet(&mut pkt);
26
27            Packet(pkt)
28        }
29    }
30
31    #[inline]
32    pub fn new(size: usize) -> Self {
33        unsafe {
34            let mut pkt: AVPacket = mem::zeroed();
35
36            av_init_packet(&mut pkt);
37            av_new_packet(&mut pkt, size as c_int);
38
39            Packet(pkt)
40        }
41    }
42
43    #[inline]
44    pub fn copy(data: &[u8]) -> Self {
45        use std::io::Write;
46
47        let mut packet = Packet::new(data.len());
48        packet.data_mut().unwrap().write_all(data).unwrap();
49
50        packet
51    }
52
53    #[inline]
54    pub fn borrow(data: &[u8]) -> Borrow<'_> {
55        Borrow::new(data)
56    }
57
58    #[inline]
59    pub fn shrink(&mut self, size: usize) {
60        unsafe {
61            av_shrink_packet(&mut self.0, size as c_int);
62        }
63    }
64
65    #[inline]
66    pub fn grow(&mut self, size: usize) {
67        unsafe {
68            av_grow_packet(&mut self.0, size as c_int);
69        }
70    }
71
72    #[inline]
73    pub fn rescale_ts<S, D>(&mut self, source: S, destination: D)
74    where
75        S: Into<Rational>,
76        D: Into<Rational>,
77    {
78        unsafe {
79            av_packet_rescale_ts(self.as_mut_ptr(), source.into().into(), destination.into().into());
80        }
81    }
82
83    #[inline]
84    pub fn flags(&self) -> Flags {
85        Flags::from_bits_truncate(self.0.flags)
86    }
87
88    #[inline]
89    pub fn set_flags(&mut self, value: Flags) {
90        self.0.flags = value.bits();
91    }
92
93    #[inline]
94    pub fn is_key(&self) -> bool {
95        self.flags().contains(Flags::KEY)
96    }
97
98    #[inline]
99    pub fn is_corrupt(&self) -> bool {
100        self.flags().contains(Flags::CORRUPT)
101    }
102
103    #[inline]
104    pub fn stream(&self) -> usize {
105        self.0.stream_index as usize
106    }
107
108    #[inline]
109    pub fn set_stream(&mut self, index: usize) {
110        self.0.stream_index = index as c_int;
111    }
112
113    #[inline]
114    pub fn pts(&self) -> Option<i64> {
115        match self.0.pts {
116            AV_NOPTS_VALUE => None,
117            pts => Some(pts),
118        }
119    }
120
121    #[inline]
122    pub fn set_pts(&mut self, value: Option<i64>) {
123        self.0.pts = value.unwrap_or(AV_NOPTS_VALUE);
124    }
125
126    #[inline]
127    pub fn dts(&self) -> Option<i64> {
128        match self.0.dts {
129            AV_NOPTS_VALUE => None,
130            dts => Some(dts),
131        }
132    }
133
134    #[inline]
135    pub fn set_dts(&mut self, value: Option<i64>) {
136        self.0.dts = value.unwrap_or(AV_NOPTS_VALUE);
137    }
138
139    #[inline]
140    #[cfg(feature = "ffmpeg_5_0")]
141    pub fn time_base(&self) -> Rational {
142        self.0.time_base.into()
143    }
144
145    #[inline]
146    #[cfg(feature = "ffmpeg_5_0")]
147    pub fn set_time_base(&mut self, value: Rational) {
148        self.0.time_base = value.into();
149    }
150
151    #[inline]
152    pub fn size(&self) -> usize {
153        self.0.size as usize
154    }
155
156    #[inline]
157    pub fn duration(&self) -> i64 {
158        self.0.duration
159    }
160
161    #[inline]
162    pub fn set_duration(&mut self, value: i64) {
163        self.0.duration = value;
164    }
165
166    #[inline]
167    pub fn position(&self) -> isize {
168        self.0.pos as isize
169    }
170
171    #[inline]
172    pub fn set_position(&mut self, value: isize) {
173        self.0.pos = value as i64
174    }
175
176    #[inline]
177    #[cfg(not(feature = "ffmpeg_5_0"))]
178    pub fn convergence(&self) -> isize {
179        self.0.convergence_duration as isize
180    }
181
182    #[inline]
183    pub fn side_data(&self) -> SideDataIter<'_> {
184        SideDataIter::new(&self.0)
185    }
186
187    #[inline]
188    pub fn data(&self) -> Option<&[u8]> {
189        unsafe { if self.0.data.is_null() { None } else { Some(slice::from_raw_parts(self.0.data, self.0.size as usize)) } }
190    }
191
192    #[inline]
193    pub fn data_mut(&mut self) -> Option<&mut [u8]> {
194        unsafe { if self.0.data.is_null() { None } else { Some(slice::from_raw_parts_mut(self.0.data, self.0.size as usize)) } }
195    }
196
197    #[inline]
198    pub fn read(&mut self, format: &mut format::context::Input) -> Result<(), Error> {
199        unsafe {
200            match av_read_frame(format.as_mut_ptr(), self.as_mut_ptr()) {
201                0 => Ok(()),
202                e => Err(Error::from(e)),
203            }
204        }
205    }
206
207    #[inline]
208    pub fn write(&self, format: &mut format::context::Output) -> Result<bool, Error> {
209        unsafe {
210            if self.is_empty() {
211                return Err(Error::InvalidData);
212            }
213
214            match av_write_frame(format.as_mut_ptr(), self.as_ptr() as *mut _) {
215                1 => Ok(true),
216                0 => Ok(false),
217                e => Err(Error::from(e)),
218            }
219        }
220    }
221
222    #[inline]
223    pub fn write_interleaved(&self, format: &mut format::context::Output) -> Result<(), Error> {
224        unsafe {
225            if self.is_empty() {
226                return Err(Error::InvalidData);
227            }
228
229            match av_interleaved_write_frame(format.as_mut_ptr(), self.as_ptr() as *mut _) {
230                0 => Ok(()),
231                e => Err(Error::from(e)),
232            }
233        }
234    }
235}
236
237impl Ref for Packet {
238    fn as_ptr(&self) -> *const AVPacket {
239        &self.0
240    }
241}
242
243impl Mut for Packet {
244    fn as_mut_ptr(&mut self) -> *mut AVPacket {
245        &mut self.0
246    }
247}
248
249impl Clone for Packet {
250    #[inline]
251    fn clone(&self) -> Self {
252        let mut pkt = Packet::empty();
253        pkt.clone_from(self);
254
255        pkt
256    }
257
258    #[inline]
259    fn clone_from(&mut self, source: &Self) {
260        #[cfg(feature = "ffmpeg_4_0")]
261        unsafe {
262            av_packet_ref(&mut self.0, &source.0);
263            av_packet_make_writable(&mut self.0);
264        }
265        #[cfg(not(feature = "ffmpeg_4_0"))]
266        unsafe {
267            av_copy_packet(&mut self.0, &source.0);
268        }
269    }
270}
271
272impl Drop for Packet {
273    fn drop(&mut self) {
274        unsafe {
275            av_packet_unref(&mut self.0);
276        }
277    }
278}
279
280pub struct SideDataIter<'a> {
281    ptr: *const AVPacket,
282    cur: c_int,
283
284    _marker: PhantomData<&'a Packet>,
285}
286
287impl<'a> SideDataIter<'a> {
288    pub fn new(ptr: *const AVPacket) -> Self {
289        SideDataIter { ptr, cur: 0, _marker: PhantomData }
290    }
291}
292
293impl<'a> Iterator for SideDataIter<'a> {
294    type Item = SideData<'a>;
295
296    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
297        unsafe {
298            if self.cur >= (*self.ptr).side_data_elems {
299                None
300            } else {
301                self.cur += 1;
302                Some(SideData::wrap((*self.ptr).side_data.offset((self.cur - 1) as isize)))
303            }
304        }
305    }
306
307    fn size_hint(&self) -> (usize, Option<usize>) {
308        unsafe {
309            let length = (*self.ptr).side_data_elems as usize;
310
311            (length - self.cur as usize, Some(length - self.cur as usize))
312        }
313    }
314}
315
316impl<'a> ExactSizeIterator for SideDataIter<'a> {}