Skip to main content

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