1 | use std::ffi::CStr; |
2 | use std::marker::PhantomData; |
3 | use std::slice; |
4 | use std::str::from_utf8_unchecked; |
5 | |
6 | use super::Frame; |
7 | use ffi::AVFrameSideDataType::*; |
8 | use ffi::*; |
9 | use DictionaryRef; |
10 | |
11 | #[derive (Eq, PartialEq, Copy, Clone, Debug)] |
12 | pub enum Type { |
13 | PanScan, |
14 | A53CC, |
15 | Stereo3D, |
16 | MatrixEncoding, |
17 | DownMixInfo, |
18 | ReplayGain, |
19 | DisplayMatrix, |
20 | AFD, |
21 | MotionVectors, |
22 | SkipSamples, |
23 | AudioServiceType, |
24 | MasteringDisplayMetadata, |
25 | GOPTimecode, |
26 | Spherical, |
27 | |
28 | ContentLightLevel, |
29 | IccProfile, |
30 | |
31 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
32 | QPTableProperties, |
33 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
34 | QPTableData, |
35 | |
36 | #[cfg (feature = "ffmpeg_4_1" )] |
37 | S12M_TIMECODE, |
38 | |
39 | #[cfg (feature = "ffmpeg_4_2" )] |
40 | DYNAMIC_HDR_PLUS, |
41 | #[cfg (feature = "ffmpeg_4_2" )] |
42 | REGIONS_OF_INTEREST, |
43 | |
44 | #[cfg (feature = "ffmpeg_4_3" )] |
45 | VIDEO_ENC_PARAMS, |
46 | |
47 | #[cfg (feature = "ffmpeg_4_4" )] |
48 | SEI_UNREGISTERED, |
49 | #[cfg (feature = "ffmpeg_4_4" )] |
50 | FILM_GRAIN_PARAMS, |
51 | |
52 | #[cfg (feature = "ffmpeg_5_0" )] |
53 | DETECTION_BBOXES, |
54 | #[cfg (feature = "ffmpeg_5_0" )] |
55 | DOVI_RPU_BUFFER, |
56 | #[cfg (feature = "ffmpeg_5_0" )] |
57 | DOVI_METADATA, |
58 | |
59 | #[cfg (feature = "ffmpeg_5_1" )] |
60 | DYNAMIC_HDR_VIVID, |
61 | |
62 | #[cfg (feature = "ffmpeg_6_0" )] |
63 | AMBIENT_VIEWING_ENVIRONMENT, |
64 | |
65 | #[cfg (feature = "ffmpeg_6_1" )] |
66 | VIDEO_HINT, |
67 | |
68 | #[cfg (feature = "ffmpeg_7_1" )] |
69 | LCEVC, |
70 | #[cfg (feature = "ffmpeg_7_1" )] |
71 | VIEW_ID, |
72 | } |
73 | |
74 | impl Type { |
75 | #[inline ] |
76 | pub fn name(&self) -> &'static str { |
77 | unsafe { |
78 | from_utf8_unchecked(CStr::from_ptr(av_frame_side_data_name((*self).into())).to_bytes()) |
79 | } |
80 | } |
81 | } |
82 | |
83 | impl From<AVFrameSideDataType> for Type { |
84 | #[inline (always)] |
85 | fn from(value: AVFrameSideDataType) -> Self { |
86 | match value { |
87 | AV_FRAME_DATA_PANSCAN => Type::PanScan, |
88 | AV_FRAME_DATA_A53_CC => Type::A53CC, |
89 | AV_FRAME_DATA_STEREO3D => Type::Stereo3D, |
90 | AV_FRAME_DATA_MATRIXENCODING => Type::MatrixEncoding, |
91 | AV_FRAME_DATA_DOWNMIX_INFO => Type::DownMixInfo, |
92 | AV_FRAME_DATA_REPLAYGAIN => Type::ReplayGain, |
93 | AV_FRAME_DATA_DISPLAYMATRIX => Type::DisplayMatrix, |
94 | AV_FRAME_DATA_AFD => Type::AFD, |
95 | AV_FRAME_DATA_MOTION_VECTORS => Type::MotionVectors, |
96 | AV_FRAME_DATA_SKIP_SAMPLES => Type::SkipSamples, |
97 | AV_FRAME_DATA_AUDIO_SERVICE_TYPE => Type::AudioServiceType, |
98 | AV_FRAME_DATA_MASTERING_DISPLAY_METADATA => Type::MasteringDisplayMetadata, |
99 | AV_FRAME_DATA_GOP_TIMECODE => Type::GOPTimecode, |
100 | AV_FRAME_DATA_SPHERICAL => Type::Spherical, |
101 | |
102 | AV_FRAME_DATA_CONTENT_LIGHT_LEVEL => Type::ContentLightLevel, |
103 | AV_FRAME_DATA_ICC_PROFILE => Type::IccProfile, |
104 | |
105 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
106 | AV_FRAME_DATA_QP_TABLE_PROPERTIES => Type::QPTableProperties, |
107 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
108 | AV_FRAME_DATA_QP_TABLE_DATA => Type::QPTableData, |
109 | #[cfg (feature = "ffmpeg_4_1" )] |
110 | AV_FRAME_DATA_S12M_TIMECODE => Type::S12M_TIMECODE, |
111 | |
112 | #[cfg (feature = "ffmpeg_4_2" )] |
113 | AV_FRAME_DATA_DYNAMIC_HDR_PLUS => Type::DYNAMIC_HDR_PLUS, |
114 | #[cfg (feature = "ffmpeg_4_2" )] |
115 | AV_FRAME_DATA_REGIONS_OF_INTEREST => Type::REGIONS_OF_INTEREST, |
116 | |
117 | #[cfg (feature = "ffmpeg_4_3" )] |
118 | AV_FRAME_DATA_VIDEO_ENC_PARAMS => Type::VIDEO_ENC_PARAMS, |
119 | |
120 | #[cfg (feature = "ffmpeg_4_4" )] |
121 | AV_FRAME_DATA_SEI_UNREGISTERED => Type::SEI_UNREGISTERED, |
122 | #[cfg (feature = "ffmpeg_4_4" )] |
123 | AV_FRAME_DATA_FILM_GRAIN_PARAMS => Type::FILM_GRAIN_PARAMS, |
124 | |
125 | #[cfg (feature = "ffmpeg_5_0" )] |
126 | AV_FRAME_DATA_DETECTION_BBOXES => Type::DETECTION_BBOXES, |
127 | #[cfg (feature = "ffmpeg_5_0" )] |
128 | AV_FRAME_DATA_DOVI_RPU_BUFFER => Type::DOVI_RPU_BUFFER, |
129 | #[cfg (feature = "ffmpeg_5_0" )] |
130 | AV_FRAME_DATA_DOVI_METADATA => Type::DOVI_METADATA, |
131 | |
132 | #[cfg (feature = "ffmpeg_5_1" )] |
133 | AV_FRAME_DATA_DYNAMIC_HDR_VIVID => Type::DYNAMIC_HDR_VIVID, |
134 | |
135 | #[cfg (feature = "ffmpeg_6_0" )] |
136 | AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT => Type::AMBIENT_VIEWING_ENVIRONMENT, |
137 | |
138 | #[cfg (feature = "ffmpeg_6_1" )] |
139 | AV_FRAME_DATA_VIDEO_HINT => Type::VIDEO_HINT, |
140 | |
141 | #[cfg (feature = "ffmpeg_7_1" )] |
142 | AV_FRAME_DATA_LCEVC => Type::LCEVC, |
143 | #[cfg (feature = "ffmpeg_7_1" )] |
144 | AV_FRAME_DATA_VIEW_ID => Type::VIEW_ID, |
145 | } |
146 | } |
147 | } |
148 | |
149 | impl From<Type> for AVFrameSideDataType { |
150 | #[inline (always)] |
151 | fn from(value: Type) -> AVFrameSideDataType { |
152 | match value { |
153 | Type::PanScan => AV_FRAME_DATA_PANSCAN, |
154 | Type::A53CC => AV_FRAME_DATA_A53_CC, |
155 | Type::Stereo3D => AV_FRAME_DATA_STEREO3D, |
156 | Type::MatrixEncoding => AV_FRAME_DATA_MATRIXENCODING, |
157 | Type::DownMixInfo => AV_FRAME_DATA_DOWNMIX_INFO, |
158 | Type::ReplayGain => AV_FRAME_DATA_REPLAYGAIN, |
159 | Type::DisplayMatrix => AV_FRAME_DATA_DISPLAYMATRIX, |
160 | Type::AFD => AV_FRAME_DATA_AFD, |
161 | Type::MotionVectors => AV_FRAME_DATA_MOTION_VECTORS, |
162 | Type::SkipSamples => AV_FRAME_DATA_SKIP_SAMPLES, |
163 | Type::AudioServiceType => AV_FRAME_DATA_AUDIO_SERVICE_TYPE, |
164 | Type::MasteringDisplayMetadata => AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, |
165 | Type::GOPTimecode => AV_FRAME_DATA_GOP_TIMECODE, |
166 | Type::Spherical => AV_FRAME_DATA_SPHERICAL, |
167 | |
168 | Type::ContentLightLevel => AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, |
169 | Type::IccProfile => AV_FRAME_DATA_ICC_PROFILE, |
170 | |
171 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
172 | Type::QPTableProperties => AV_FRAME_DATA_QP_TABLE_PROPERTIES, |
173 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
174 | Type::QPTableData => AV_FRAME_DATA_QP_TABLE_DATA, |
175 | #[cfg (feature = "ffmpeg_4_1" )] |
176 | Type::S12M_TIMECODE => AV_FRAME_DATA_S12M_TIMECODE, |
177 | |
178 | #[cfg (feature = "ffmpeg_4_2" )] |
179 | Type::DYNAMIC_HDR_PLUS => AV_FRAME_DATA_DYNAMIC_HDR_PLUS, |
180 | #[cfg (feature = "ffmpeg_4_2" )] |
181 | Type::REGIONS_OF_INTEREST => AV_FRAME_DATA_REGIONS_OF_INTEREST, |
182 | |
183 | #[cfg (feature = "ffmpeg_4_3" )] |
184 | Type::VIDEO_ENC_PARAMS => AV_FRAME_DATA_VIDEO_ENC_PARAMS, |
185 | |
186 | #[cfg (feature = "ffmpeg_4_4" )] |
187 | Type::SEI_UNREGISTERED => AV_FRAME_DATA_SEI_UNREGISTERED, |
188 | #[cfg (feature = "ffmpeg_4_4" )] |
189 | Type::FILM_GRAIN_PARAMS => AV_FRAME_DATA_FILM_GRAIN_PARAMS, |
190 | |
191 | #[cfg (feature = "ffmpeg_5_0" )] |
192 | Type::DETECTION_BBOXES => AV_FRAME_DATA_DETECTION_BBOXES, |
193 | #[cfg (feature = "ffmpeg_5_0" )] |
194 | Type::DOVI_RPU_BUFFER => AV_FRAME_DATA_DOVI_RPU_BUFFER, |
195 | #[cfg (feature = "ffmpeg_5_0" )] |
196 | Type::DOVI_METADATA => AV_FRAME_DATA_DOVI_METADATA, |
197 | |
198 | #[cfg (feature = "ffmpeg_5_1" )] |
199 | Type::DYNAMIC_HDR_VIVID => AV_FRAME_DATA_DYNAMIC_HDR_VIVID, |
200 | |
201 | #[cfg (feature = "ffmpeg_6_0" )] |
202 | Type::AMBIENT_VIEWING_ENVIRONMENT => AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, |
203 | |
204 | #[cfg (feature = "ffmpeg_6_1" )] |
205 | Type::VIDEO_HINT => AV_FRAME_DATA_VIDEO_HINT, |
206 | |
207 | #[cfg (feature = "ffmpeg_7_1" )] |
208 | Type::LCEVC => AV_FRAME_DATA_LCEVC, |
209 | #[cfg (feature = "ffmpeg_7_1" )] |
210 | Type::VIEW_ID => AV_FRAME_DATA_VIEW_ID, |
211 | } |
212 | } |
213 | } |
214 | |
215 | pub struct SideData<'a> { |
216 | ptr: *mut AVFrameSideData, |
217 | |
218 | _marker: PhantomData<&'a Frame>, |
219 | } |
220 | |
221 | impl<'a> SideData<'a> { |
222 | #[inline (always)] |
223 | pub unsafe fn wrap(ptr: *mut AVFrameSideData) -> Self { |
224 | SideData { |
225 | ptr, |
226 | _marker: PhantomData, |
227 | } |
228 | } |
229 | |
230 | #[inline (always)] |
231 | pub unsafe fn as_ptr(&self) -> *const AVFrameSideData { |
232 | self.ptr as *const _ |
233 | } |
234 | |
235 | #[inline (always)] |
236 | pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrameSideData { |
237 | self.ptr |
238 | } |
239 | } |
240 | |
241 | impl<'a> SideData<'a> { |
242 | #[inline ] |
243 | pub fn kind(&self) -> Type { |
244 | unsafe { Type::from((*self.as_ptr()).type_) } |
245 | } |
246 | |
247 | #[inline ] |
248 | pub fn data(&self) -> &[u8] { |
249 | #[allow (clippy::unnecessary_cast)] |
250 | unsafe { |
251 | slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize) |
252 | } |
253 | } |
254 | |
255 | #[inline ] |
256 | pub fn metadata(&self) -> DictionaryRef { |
257 | unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) } |
258 | } |
259 | } |
260 | |