playa_ffmpeg/util/frame/
mod.rs

1pub mod side_data;
2pub use self::side_data::SideData;
3
4pub mod video;
5pub use self::video::Video;
6
7pub mod audio;
8pub use self::audio::Audio;
9
10pub mod flag;
11pub use self::flag::Flags;
12
13use crate::{Dictionary, DictionaryRef, ffi::*};
14
15#[derive(PartialEq, Eq, Copy, Clone, Debug)]
16pub struct Packet {
17    pub duration: i64,
18    #[cfg(not(feature = "ffmpeg_8_0"))]
19    pub position: i64,
20    #[cfg(not(feature = "ffmpeg_8_0"))]
21    pub size: usize,
22
23    #[cfg(not(feature = "ffmpeg_5_0"))]
24    pub pts: i64,
25    pub dts: i64,
26}
27
28#[derive(PartialEq, Eq)]
29pub struct Frame {
30    ptr: *mut AVFrame,
31
32    _own: bool,
33}
34
35unsafe impl Send for Frame {}
36unsafe impl Sync for Frame {}
37
38impl Frame {
39    #[inline(always)]
40    pub unsafe fn wrap(ptr: *mut AVFrame) -> Self {
41        Frame { ptr, _own: false }
42    }
43
44    #[inline(always)]
45    pub unsafe fn empty() -> Self {
46        Frame { ptr: unsafe { av_frame_alloc() }, _own: true }
47    }
48
49    #[inline(always)]
50    pub unsafe fn as_ptr(&self) -> *const AVFrame {
51        self.ptr as *const _
52    }
53
54    #[inline(always)]
55    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrame {
56        self.ptr
57    }
58
59    #[inline(always)]
60    pub unsafe fn is_empty(&self) -> bool {
61        unsafe { (*self.as_ptr()).data[0].is_null() }
62    }
63}
64
65impl Frame {
66    #[inline]
67    pub fn is_key(&self) -> bool {
68        #[cfg(not(feature = "ffmpeg_8_0"))]
69        unsafe {
70            (*self.as_ptr()).key_frame == 1
71        }
72        #[cfg(feature = "ffmpeg_8_0")]
73        unsafe {
74            ((*self.as_ptr()).flags & AV_FRAME_FLAG_KEY) != 0
75        }
76    }
77
78    #[inline]
79    pub fn is_corrupt(&self) -> bool {
80        self.flags().contains(Flags::CORRUPT)
81    }
82
83    #[inline]
84    pub fn packet(&self) -> Packet {
85        unsafe {
86            Packet {
87                #[cfg(not(feature = "ffmpeg_7_0"))]
88                duration: (*self.as_ptr()).pkt_duration,
89                #[cfg(feature = "ffmpeg_7_0")]
90                duration: (*self.as_ptr()).duration,
91
92                #[cfg(not(feature = "ffmpeg_8_0"))]
93                position: (*self.as_ptr()).pkt_pos,
94                #[cfg(not(feature = "ffmpeg_8_0"))]
95                size: (*self.as_ptr()).pkt_size as usize,
96
97                #[cfg(not(feature = "ffmpeg_5_0"))]
98                pts: (*self.as_ptr()).pkt_pts,
99                dts: (*self.as_ptr()).pkt_dts,
100            }
101        }
102    }
103
104    #[inline]
105    pub fn pts(&self) -> Option<i64> {
106        unsafe {
107            match (*self.as_ptr()).pts {
108                AV_NOPTS_VALUE => None,
109                pts => Some(pts),
110            }
111        }
112    }
113
114    #[inline]
115    pub fn set_pts(&mut self, value: Option<i64>) {
116        unsafe {
117            (*self.as_mut_ptr()).pts = value.unwrap_or(AV_NOPTS_VALUE);
118        }
119    }
120
121    #[inline]
122    pub fn timestamp(&self) -> Option<i64> {
123        unsafe {
124            match (*self.as_ptr()).best_effort_timestamp {
125                AV_NOPTS_VALUE => None,
126                t => Some(t),
127            }
128        }
129    }
130
131    #[inline]
132    pub fn quality(&self) -> usize {
133        unsafe { (*self.as_ptr()).quality as usize }
134    }
135
136    #[inline]
137    pub fn flags(&self) -> Flags {
138        unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
139    }
140
141    #[inline]
142    pub fn metadata(&self) -> DictionaryRef<'_> {
143        unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) }
144    }
145
146    #[inline]
147    pub fn set_metadata(&mut self, value: Dictionary) {
148        unsafe { (*self.as_mut_ptr()).metadata = value.disown() }
149    }
150
151    #[inline]
152    pub fn side_data(&self, kind: side_data::Type) -> Option<SideData<'_>> {
153        unsafe {
154            let ptr = av_frame_get_side_data(self.as_ptr(), kind.into());
155
156            if ptr.is_null() { None } else { Some(SideData::wrap(ptr)) }
157        }
158    }
159
160    #[inline]
161    pub fn new_side_data(&mut self, kind: side_data::Type, size: usize) -> Option<SideData<'_>> {
162        unsafe {
163            let ptr = av_frame_new_side_data(self.as_mut_ptr(), kind.into(), size as _);
164
165            if ptr.is_null() { None } else { Some(SideData::wrap(ptr)) }
166        }
167    }
168
169    #[inline]
170    pub fn remove_side_data(&mut self, kind: side_data::Type) {
171        unsafe {
172            av_frame_remove_side_data(self.as_mut_ptr(), kind.into());
173        }
174    }
175}
176
177impl Drop for Frame {
178    #[inline]
179    fn drop(&mut self) {
180        unsafe {
181            av_frame_free(&mut self.as_mut_ptr());
182        }
183    }
184}