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