playa_ffmpeg/codec/packet/
packet.rs1use 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> {}