1use std::marker::PhantomData;
2use std::mem;
3use std::slice;
4
5use super::{Borrow, Flags, Mut, Ref, SideData};
6use ffi::*;
7use libc::c_int;
8use {format, Error, Rational};
9
10pub struct Packet(AVPacket);
11
12unsafe impl Send for Packet {}
13unsafe impl Sync for Packet {}
14
15impl Packet {
16 #[inline(always)]
17 pub unsafe fn is_empty(&self) -> bool {
18 self.0.size == 0
19 }
20}
21
22impl 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
256impl Ref for Packet {
257 fn as_ptr(&self) -> *const AVPacket {
258 &self.0
259 }
260}
261
262impl Mut for Packet {
263 fn as_mut_ptr(&mut self) -> *mut AVPacket {
264 &mut self.0
265 }
266}
267
268impl 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
291impl Drop for Packet {
292 fn drop(&mut self) {
293 unsafe {
294 av_packet_unref(&mut self.0);
295 }
296 }
297}
298
299pub struct SideDataIter<'a> {
300 ptr: *const AVPacket,
301 cur: c_int,
302
303 _marker: PhantomData<&'a Packet>,
304}
305
306impl<'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
316impl<'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
341impl<'a> ExactSizeIterator for SideDataIter<'a> {}
342