ffmpeg_next/util/frame/
mod.rs1pub 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}