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 | pub fn size(&self) -> usize { |
148 | self.0.size as usize |
149 | } |
150 | |
151 | #[inline ] |
152 | pub fn duration(&self) -> i64 { |
153 | self.0.duration |
154 | } |
155 | |
156 | #[inline ] |
157 | pub fn set_duration(&mut self, value: i64) { |
158 | self.0.duration = value; |
159 | } |
160 | |
161 | #[inline ] |
162 | pub fn position(&self) -> isize { |
163 | self.0.pos as isize |
164 | } |
165 | |
166 | #[inline ] |
167 | pub fn set_position(&mut self, value: isize) { |
168 | self.0.pos = value as i64 |
169 | } |
170 | |
171 | #[inline ] |
172 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
173 | pub fn convergence(&self) -> isize { |
174 | self.0.convergence_duration as isize |
175 | } |
176 | |
177 | #[inline ] |
178 | pub fn side_data(&self) -> SideDataIter { |
179 | SideDataIter::new(&self.0) |
180 | } |
181 | |
182 | #[inline ] |
183 | pub fn data(&self) -> Option<&[u8]> { |
184 | unsafe { |
185 | if self.0.data.is_null() { |
186 | None |
187 | } else { |
188 | Some(slice::from_raw_parts(self.0.data, self.0.size as usize)) |
189 | } |
190 | } |
191 | } |
192 | |
193 | #[inline ] |
194 | pub fn data_mut(&mut self) -> Option<&mut [u8]> { |
195 | unsafe { |
196 | if self.0.data.is_null() { |
197 | None |
198 | } else { |
199 | Some(slice::from_raw_parts_mut(self.0.data, self.0.size as usize)) |
200 | } |
201 | } |
202 | } |
203 | |
204 | #[inline ] |
205 | pub fn read(&mut self, format: &mut format::context::Input) -> Result<(), Error> { |
206 | unsafe { |
207 | match av_read_frame(format.as_mut_ptr(), self.as_mut_ptr()) { |
208 | 0 => Ok(()), |
209 | e => Err(Error::from(e)), |
210 | } |
211 | } |
212 | } |
213 | |
214 | #[inline ] |
215 | pub fn write(&self, format: &mut format::context::Output) -> Result<bool, Error> { |
216 | unsafe { |
217 | if self.is_empty() { |
218 | return Err(Error::InvalidData); |
219 | } |
220 | |
221 | match av_write_frame(format.as_mut_ptr(), self.as_ptr() as *mut _) { |
222 | 1 => Ok(true), |
223 | 0 => Ok(false), |
224 | e => Err(Error::from(e)), |
225 | } |
226 | } |
227 | } |
228 | |
229 | #[inline ] |
230 | pub fn write_interleaved(&self, format: &mut format::context::Output) -> Result<(), Error> { |
231 | unsafe { |
232 | if self.is_empty() { |
233 | return Err(Error::InvalidData); |
234 | } |
235 | |
236 | match av_interleaved_write_frame(format.as_mut_ptr(), self.as_ptr() as *mut _) { |
237 | 0 => Ok(()), |
238 | e => Err(Error::from(e)), |
239 | } |
240 | } |
241 | } |
242 | } |
243 | |
244 | impl Ref for Packet { |
245 | fn as_ptr(&self) -> *const AVPacket { |
246 | &self.0 |
247 | } |
248 | } |
249 | |
250 | impl Mut for Packet { |
251 | fn as_mut_ptr(&mut self) -> *mut AVPacket { |
252 | &mut self.0 |
253 | } |
254 | } |
255 | |
256 | impl Clone for Packet { |
257 | #[inline ] |
258 | fn clone(&self) -> Self { |
259 | let mut pkt: Packet = Packet::empty(); |
260 | pkt.clone_from(self); |
261 | |
262 | pkt |
263 | } |
264 | |
265 | #[inline ] |
266 | fn clone_from(&mut self, source: &Self) { |
267 | #[cfg (feature = "ffmpeg_4_0" )] |
268 | unsafe { |
269 | av_packet_ref(&mut self.0, &source.0); |
270 | av_packet_make_writable(&mut self.0); |
271 | } |
272 | #[cfg (not(feature = "ffmpeg_4_0" ))] |
273 | unsafe { |
274 | av_copy_packet(&mut self.0, &source.0); |
275 | } |
276 | } |
277 | } |
278 | |
279 | impl Drop for Packet { |
280 | fn drop(&mut self) { |
281 | unsafe { |
282 | av_packet_unref(&mut self.0); |
283 | } |
284 | } |
285 | } |
286 | |
287 | pub struct SideDataIter<'a> { |
288 | ptr: *const AVPacket, |
289 | cur: c_int, |
290 | |
291 | _marker: PhantomData<&'a Packet>, |
292 | } |
293 | |
294 | impl<'a> SideDataIter<'a> { |
295 | pub fn new(ptr: *const AVPacket) -> Self { |
296 | SideDataIter { |
297 | ptr, |
298 | cur: 0, |
299 | _marker: PhantomData, |
300 | } |
301 | } |
302 | } |
303 | |
304 | impl<'a> Iterator for SideDataIter<'a> { |
305 | type Item = SideData<'a>; |
306 | |
307 | fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
308 | unsafe { |
309 | if self.cur >= (*self.ptr).side_data_elems { |
310 | None |
311 | } else { |
312 | self.cur += 1; |
313 | Some(SideData::wrap( |
314 | (*self.ptr).side_data.offset((self.cur - 1) as isize), |
315 | )) |
316 | } |
317 | } |
318 | } |
319 | |
320 | fn size_hint(&self) -> (usize, Option<usize>) { |
321 | unsafe { |
322 | let length: usize = (*self.ptr).side_data_elems as usize; |
323 | |
324 | (length - self.cur as usize, Some(length - self.cur as usize)) |
325 | } |
326 | } |
327 | } |
328 | |
329 | impl<'a> ExactSizeIterator for SideDataIter<'a> {} |
330 | |