1use std::{
7 ffi::CStr,
8 os::raw::{c_char, c_int, c_void},
9 ptr, slice,
10 time::Duration,
11};
12
13use crate::time::{TimeBase, Timestamp};
14
15extern "C" {
16 fn ffw_packet_alloc() -> *mut c_void;
17 fn ffw_packet_new(size: c_int) -> *mut c_void;
18 fn ffw_packet_clone(src: *const c_void) -> *mut c_void;
19 fn ffw_packet_free(packet: *mut c_void);
20 fn ffw_packet_get_size(packet: *const c_void) -> c_int;
21 fn ffw_packet_get_data(packet: *mut c_void) -> *mut c_void;
22 fn ffw_packet_get_pts(packet: *const c_void) -> i64;
23 fn ffw_packet_set_pts(packet: *mut c_void, pts: i64);
24 fn ffw_packet_get_dts(packet: *const c_void) -> i64;
25 fn ffw_packet_set_dts(packet: *mut c_void, pts: i64);
26 fn ffw_packet_get_duration(packet: *const c_void) -> i64;
27 fn ffw_packet_set_duration(packet: *mut c_void, duration: i64);
28 fn ffw_packet_is_key(packet: *const c_void) -> c_int;
29 fn ffw_packet_set_key(packet: *mut c_void, key: c_int);
30 fn ffw_packet_get_stream_index(packet: *const c_void) -> c_int;
31 fn ffw_packet_set_stream_index(packet: *mut c_void, index: c_int);
32 fn ffw_packet_is_writable(packet: *const c_void) -> c_int;
33 fn ffw_packet_make_writable(packet: *mut c_void) -> c_int;
34 fn ffw_packet_side_data_get_size(side_data: *const c_void) -> usize;
35 fn ffw_packet_side_data_get_data(side_data: *const c_void) -> *const u8;
36 fn ffw_packet_side_data_get_type(side_data: *const c_void) -> c_int;
37 fn ffw_packet_get_side_data_name(side_data_type: c_int) -> *const c_char;
38}
39
40pub struct PacketMut {
42 ptr: *mut c_void,
43 time_base: TimeBase,
44}
45
46impl PacketMut {
47 pub fn new(size: usize) -> Self {
50 unsafe {
51 let ptr = if size == 0 {
52 ffw_packet_alloc()
53 } else {
54 ffw_packet_new(size as c_int)
55 };
56
57 if ptr.is_null() {
58 panic!("unable to allocate a packet");
59 }
60
61 Self {
62 ptr,
63 time_base: TimeBase::MICROSECONDS,
64 }
65 }
66 }
67
68 pub fn stream_index(&self) -> usize {
70 unsafe { ffw_packet_get_stream_index(self.ptr) as _ }
71 }
72
73 pub fn with_stream_index(self, index: usize) -> Self {
75 unsafe { ffw_packet_set_stream_index(self.ptr, index as _) }
76
77 self
78 }
79
80 #[inline]
82 pub fn time_base(&self) -> TimeBase {
83 self.time_base
84 }
85
86 pub fn with_time_base(mut self, time_base: TimeBase) -> Self {
89 let new_pts = self.pts().with_time_base(time_base);
90 let new_dts = self.dts().with_time_base(time_base);
91
92 unsafe {
93 ffw_packet_set_pts(self.ptr, new_pts.timestamp());
94 ffw_packet_set_dts(self.ptr, new_dts.timestamp());
95 }
96
97 self.time_base = time_base;
98
99 self
100 }
101
102 pub fn pts(&self) -> Timestamp {
104 let pts = unsafe { ffw_packet_get_pts(self.ptr) };
105
106 Timestamp::new(pts, self.time_base)
107 }
108
109 pub fn with_pts(self, pts: Timestamp) -> Self {
111 let pts = pts.with_time_base(self.time_base);
112
113 unsafe { ffw_packet_set_pts(self.ptr, pts.timestamp()) }
114
115 self
116 }
117
118 pub fn with_raw_pts(self, pts: i64) -> Self {
120 unsafe { ffw_packet_set_pts(self.ptr, pts) }
121
122 self
123 }
124
125 pub fn dts(&self) -> Timestamp {
127 let dts = unsafe { ffw_packet_get_dts(self.ptr) };
128
129 Timestamp::new(dts, self.time_base)
130 }
131
132 pub fn with_dts(self, dts: Timestamp) -> Self {
134 let dts = dts.with_time_base(self.time_base);
135
136 unsafe { ffw_packet_set_dts(self.ptr, dts.timestamp()) }
137
138 self
139 }
140
141 pub fn with_raw_dts(self, dts: i64) -> Self {
143 unsafe { ffw_packet_set_dts(self.ptr, dts) }
144
145 self
146 }
147
148 pub fn duration(&self) -> Option<Duration> {
152 let duration = self.raw_duration();
153
154 if duration > 0 {
155 let z = Timestamp::new(0, self.time_base);
156 let d = Timestamp::new(duration, self.time_base);
157
158 Some(d - z)
159 } else {
160 None
161 }
162 }
163
164 pub fn with_duration(self, duration: Duration) -> Self {
166 let d = Timestamp::new(0, self.time_base) + duration;
167
168 unsafe { ffw_packet_set_duration(self.ptr, d.timestamp()) }
169
170 self
171 }
172
173 pub fn raw_duration(&self) -> i64 {
175 unsafe { ffw_packet_get_duration(self.ptr) }
176 }
177
178 pub fn with_raw_duration(self, duration: i64) -> Self {
180 unsafe { ffw_packet_set_duration(self.ptr, duration) }
181
182 self
183 }
184
185 pub fn is_key(&self) -> bool {
187 unsafe { ffw_packet_is_key(self.ptr) != 0 }
188 }
189
190 pub fn with_key_flag(self, key: bool) -> Self {
192 unsafe { ffw_packet_set_key(self.ptr, key as _) }
193
194 self
195 }
196
197 pub fn data(&self) -> &[u8] {
199 unsafe {
200 let data = ffw_packet_get_data(self.ptr) as *const u8;
201 let size = ffw_packet_get_size(self.ptr) as usize;
202
203 if data.is_null() {
204 &[]
205 } else {
206 slice::from_raw_parts(data, size)
207 }
208 }
209 }
210
211 pub fn data_mut(&mut self) -> &mut [u8] {
213 unsafe {
214 let data = ffw_packet_get_data(self.ptr) as *mut u8;
215 let size = ffw_packet_get_size(self.ptr) as usize;
216
217 if data.is_null() {
218 &mut []
219 } else {
220 slice::from_raw_parts_mut(data, size)
221 }
222 }
223 }
224
225 pub fn freeze(mut self) -> Packet {
227 let ptr = self.ptr;
228
229 self.ptr = ptr::null_mut();
230
231 Packet {
232 ptr,
233 time_base: self.time_base,
234 }
235 }
236}
237
238impl Drop for PacketMut {
239 fn drop(&mut self) {
240 unsafe { ffw_packet_free(self.ptr) }
241 }
242}
243
244impl<T> From<T> for PacketMut
245where
246 T: AsRef<[u8]>,
247{
248 fn from(data: T) -> Self {
249 let data = data.as_ref();
250
251 let mut packet = Self::new(data.len());
252
253 packet.data_mut().copy_from_slice(data);
254
255 packet
256 }
257}
258
259unsafe impl Send for PacketMut {}
260unsafe impl Sync for PacketMut {}
261
262pub struct Packet {
264 ptr: *mut c_void,
265 time_base: TimeBase,
266}
267
268impl Packet {
269 pub(crate) unsafe fn from_raw_ptr(ptr: *mut c_void, time_base: TimeBase) -> Self {
271 Packet { ptr, time_base }
272 }
273
274 pub fn stream_index(&self) -> usize {
276 unsafe { ffw_packet_get_stream_index(self.ptr) as _ }
277 }
278
279 pub fn with_stream_index(self, index: usize) -> Packet {
281 unsafe { ffw_packet_set_stream_index(self.ptr, index as _) }
282
283 self
284 }
285
286 #[inline]
288 pub fn time_base(&self) -> TimeBase {
289 self.time_base
290 }
291
292 pub fn with_time_base(mut self, time_base: TimeBase) -> Self {
295 let new_pts = self.pts().with_time_base(time_base);
296 let new_dts = self.dts().with_time_base(time_base);
297
298 unsafe {
299 ffw_packet_set_pts(self.ptr, new_pts.timestamp());
300 ffw_packet_set_dts(self.ptr, new_dts.timestamp());
301 }
302
303 self.time_base = time_base;
304
305 self
306 }
307
308 pub fn pts(&self) -> Timestamp {
310 let pts = unsafe { ffw_packet_get_pts(self.ptr) };
311
312 Timestamp::new(pts, self.time_base)
313 }
314
315 pub fn with_pts(self, pts: Timestamp) -> Self {
317 let pts = pts.with_time_base(self.time_base);
318
319 unsafe { ffw_packet_set_pts(self.ptr, pts.timestamp()) }
320
321 self
322 }
323
324 pub fn with_raw_pts(self, pts: i64) -> Self {
326 unsafe { ffw_packet_set_pts(self.ptr, pts) }
327
328 self
329 }
330
331 pub fn dts(&self) -> Timestamp {
333 let dts = unsafe { ffw_packet_get_dts(self.ptr) };
334
335 Timestamp::new(dts, self.time_base)
336 }
337
338 pub fn with_dts(self, dts: Timestamp) -> Self {
340 let dts = dts.with_time_base(self.time_base);
341
342 unsafe { ffw_packet_set_dts(self.ptr, dts.timestamp()) }
343
344 self
345 }
346
347 pub fn with_raw_dts(self, dts: i64) -> Self {
349 unsafe { ffw_packet_set_dts(self.ptr, dts) }
350
351 self
352 }
353
354 pub fn duration(&self) -> Option<Duration> {
358 let duration = self.raw_duration();
359
360 if duration > 0 {
361 let z = Timestamp::new(0, self.time_base);
362 let d = Timestamp::new(duration, self.time_base);
363
364 Some(d - z)
365 } else {
366 None
367 }
368 }
369
370 pub fn with_duration(self, duration: Duration) -> Self {
372 let d = Timestamp::new(0, self.time_base) + duration;
373
374 unsafe { ffw_packet_set_duration(self.ptr, d.timestamp()) }
375
376 self
377 }
378
379 pub fn raw_duration(&self) -> i64 {
381 unsafe { ffw_packet_get_duration(self.ptr) }
382 }
383
384 pub fn with_raw_duration(self, duration: i64) -> Self {
386 unsafe { ffw_packet_set_duration(self.ptr, duration) }
387
388 self
389 }
390
391 pub fn is_key(&self) -> bool {
393 unsafe { ffw_packet_is_key(self.ptr) != 0 }
394 }
395
396 pub(crate) fn as_ptr(&self) -> *const c_void {
398 self.ptr
399 }
400
401 pub(crate) fn as_mut_ptr(&mut self) -> *mut c_void {
405 self.ptr
406 }
407
408 pub fn data(&self) -> &[u8] {
410 unsafe {
411 let data = ffw_packet_get_data(self.ptr) as *const u8;
412 let size = ffw_packet_get_size(self.ptr) as usize;
413
414 if data.is_null() {
415 &[]
416 } else {
417 slice::from_raw_parts(data, size)
418 }
419 }
420 }
421
422 pub fn try_into_mut(self) -> Result<PacketMut, Self> {
427 let res = unsafe { ffw_packet_is_writable(self.ptr) };
428
429 if res == 0 {
430 Err(self)
431 } else {
432 Ok(self.into_mut())
433 }
434 }
435
436 pub fn into_mut(mut self) -> PacketMut {
441 let res = unsafe { ffw_packet_make_writable(self.ptr) };
442
443 if res < 0 {
444 panic!("unable to make the packet mutable");
445 }
446
447 let ptr = self.ptr;
448
449 self.ptr = ptr::null_mut();
450
451 PacketMut {
452 ptr,
453 time_base: self.time_base,
454 }
455 }
456}
457
458impl Clone for Packet {
459 fn clone(&self) -> Packet {
460 let ptr = unsafe { ffw_packet_clone(self.ptr) };
461
462 if ptr.is_null() {
463 panic!("unable to clone a packet");
464 }
465
466 Packet {
467 ptr,
468 time_base: self.time_base,
469 }
470 }
471}
472
473impl Drop for Packet {
474 fn drop(&mut self) {
475 unsafe { ffw_packet_free(self.ptr) }
476 }
477}
478
479unsafe impl Send for Packet {}
480unsafe impl Sync for Packet {}
481
482pub struct SideDataRef(());
484
485impl SideDataRef {
486 #[cfg(any(stream_side_data, codec_params_side_data))]
488 pub(crate) unsafe fn from_raw_ptr<'a>(ptr: *const c_void) -> &'a Self {
489 unsafe { &*(ptr as *const Self) }
490 }
491
492 fn as_ptr(&self) -> *const c_void {
494 self as *const Self as _
495 }
496
497 pub fn data(&self) -> &[u8] {
499 unsafe {
500 let data = ffw_packet_side_data_get_data(self.as_ptr());
501 let len = ffw_packet_side_data_get_size(self.as_ptr());
502
503 std::slice::from_raw_parts(data, len)
504 }
505 }
506
507 pub fn data_type(&self) -> SideDataType {
509 let data_type = unsafe { ffw_packet_side_data_get_type(self.as_ptr()) };
510
511 SideDataType::from_raw(data_type)
512 }
513}
514
515pub struct SideDataType(c_int);
517
518impl SideDataType {
519 pub(crate) fn from_raw(v: c_int) -> Self {
521 Self(v)
522 }
523
524 pub(crate) fn into_raw(self) -> c_int {
526 self.0
527 }
528
529 pub fn name(self) -> &'static str {
531 unsafe {
532 let ptr = ffw_packet_get_side_data_name(self.into_raw());
533
534 if ptr.is_null() {
535 panic!("invalid packet side data type");
536 }
537
538 let name = CStr::from_ptr(ptr as _);
539
540 name.to_str().unwrap()
541 }
542 }
543}