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