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