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 | |
69 | impl Type { |
70 | #[inline ] |
71 | pub fn name(&self) -> &'static str { |
72 | unsafe { |
73 | from_utf8_unchecked(CStr::from_ptr(av_frame_side_data_name((*self).into())).to_bytes()) |
74 | } |
75 | } |
76 | } |
77 | |
78 | impl From<AVFrameSideDataType> for Type { |
79 | #[inline (always)] |
80 | fn from(value: AVFrameSideDataType) -> Self { |
81 | match value { |
82 | AV_FRAME_DATA_PANSCAN => Type::PanScan, |
83 | AV_FRAME_DATA_A53_CC => Type::A53CC, |
84 | AV_FRAME_DATA_STEREO3D => Type::Stereo3D, |
85 | AV_FRAME_DATA_MATRIXENCODING => Type::MatrixEncoding, |
86 | AV_FRAME_DATA_DOWNMIX_INFO => Type::DownMixInfo, |
87 | AV_FRAME_DATA_REPLAYGAIN => Type::ReplayGain, |
88 | AV_FRAME_DATA_DISPLAYMATRIX => Type::DisplayMatrix, |
89 | AV_FRAME_DATA_AFD => Type::AFD, |
90 | AV_FRAME_DATA_MOTION_VECTORS => Type::MotionVectors, |
91 | AV_FRAME_DATA_SKIP_SAMPLES => Type::SkipSamples, |
92 | AV_FRAME_DATA_AUDIO_SERVICE_TYPE => Type::AudioServiceType, |
93 | AV_FRAME_DATA_MASTERING_DISPLAY_METADATA => Type::MasteringDisplayMetadata, |
94 | AV_FRAME_DATA_GOP_TIMECODE => Type::GOPTimecode, |
95 | AV_FRAME_DATA_SPHERICAL => Type::Spherical, |
96 | |
97 | AV_FRAME_DATA_CONTENT_LIGHT_LEVEL => Type::ContentLightLevel, |
98 | AV_FRAME_DATA_ICC_PROFILE => Type::IccProfile, |
99 | |
100 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
101 | AV_FRAME_DATA_QP_TABLE_PROPERTIES => Type::QPTableProperties, |
102 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
103 | AV_FRAME_DATA_QP_TABLE_DATA => Type::QPTableData, |
104 | #[cfg (feature = "ffmpeg_4_1" )] |
105 | AV_FRAME_DATA_S12M_TIMECODE => Type::S12M_TIMECODE, |
106 | |
107 | #[cfg (feature = "ffmpeg_4_2" )] |
108 | AV_FRAME_DATA_DYNAMIC_HDR_PLUS => Type::DYNAMIC_HDR_PLUS, |
109 | #[cfg (feature = "ffmpeg_4_2" )] |
110 | AV_FRAME_DATA_REGIONS_OF_INTEREST => Type::REGIONS_OF_INTEREST, |
111 | |
112 | #[cfg (feature = "ffmpeg_4_3" )] |
113 | AV_FRAME_DATA_VIDEO_ENC_PARAMS => Type::VIDEO_ENC_PARAMS, |
114 | |
115 | #[cfg (feature = "ffmpeg_4_4" )] |
116 | AV_FRAME_DATA_SEI_UNREGISTERED => Type::SEI_UNREGISTERED, |
117 | #[cfg (feature = "ffmpeg_4_4" )] |
118 | AV_FRAME_DATA_FILM_GRAIN_PARAMS => Type::FILM_GRAIN_PARAMS, |
119 | |
120 | #[cfg (feature = "ffmpeg_5_0" )] |
121 | AV_FRAME_DATA_DETECTION_BBOXES => Type::DETECTION_BBOXES, |
122 | #[cfg (feature = "ffmpeg_5_0" )] |
123 | AV_FRAME_DATA_DOVI_RPU_BUFFER => Type::DOVI_RPU_BUFFER, |
124 | #[cfg (feature = "ffmpeg_5_0" )] |
125 | AV_FRAME_DATA_DOVI_METADATA => Type::DOVI_METADATA, |
126 | |
127 | #[cfg (feature = "ffmpeg_5_1" )] |
128 | AV_FRAME_DATA_DYNAMIC_HDR_VIVID => Type::DYNAMIC_HDR_VIVID, |
129 | |
130 | #[cfg (feature = "ffmpeg_6_0" )] |
131 | AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT => Type::AMBIENT_VIEWING_ENVIRONMENT, |
132 | |
133 | #[cfg (feature = "ffmpeg_6_1" )] |
134 | AV_FRAME_DATA_VIDEO_HINT => Type::VIDEO_HINT, |
135 | } |
136 | } |
137 | } |
138 | |
139 | impl From<Type> for AVFrameSideDataType { |
140 | #[inline (always)] |
141 | fn from(value: Type) -> AVFrameSideDataType { |
142 | match value { |
143 | Type::PanScan => AV_FRAME_DATA_PANSCAN, |
144 | Type::A53CC => AV_FRAME_DATA_A53_CC, |
145 | Type::Stereo3D => AV_FRAME_DATA_STEREO3D, |
146 | Type::MatrixEncoding => AV_FRAME_DATA_MATRIXENCODING, |
147 | Type::DownMixInfo => AV_FRAME_DATA_DOWNMIX_INFO, |
148 | Type::ReplayGain => AV_FRAME_DATA_REPLAYGAIN, |
149 | Type::DisplayMatrix => AV_FRAME_DATA_DISPLAYMATRIX, |
150 | Type::AFD => AV_FRAME_DATA_AFD, |
151 | Type::MotionVectors => AV_FRAME_DATA_MOTION_VECTORS, |
152 | Type::SkipSamples => AV_FRAME_DATA_SKIP_SAMPLES, |
153 | Type::AudioServiceType => AV_FRAME_DATA_AUDIO_SERVICE_TYPE, |
154 | Type::MasteringDisplayMetadata => AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, |
155 | Type::GOPTimecode => AV_FRAME_DATA_GOP_TIMECODE, |
156 | Type::Spherical => AV_FRAME_DATA_SPHERICAL, |
157 | |
158 | Type::ContentLightLevel => AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, |
159 | Type::IccProfile => AV_FRAME_DATA_ICC_PROFILE, |
160 | |
161 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
162 | Type::QPTableProperties => AV_FRAME_DATA_QP_TABLE_PROPERTIES, |
163 | #[cfg (all(feature = "ffmpeg_4_0" , not(feature = "ffmpeg_5_0" )))] |
164 | Type::QPTableData => AV_FRAME_DATA_QP_TABLE_DATA, |
165 | #[cfg (feature = "ffmpeg_4_1" )] |
166 | Type::S12M_TIMECODE => AV_FRAME_DATA_S12M_TIMECODE, |
167 | |
168 | #[cfg (feature = "ffmpeg_4_2" )] |
169 | Type::DYNAMIC_HDR_PLUS => AV_FRAME_DATA_DYNAMIC_HDR_PLUS, |
170 | #[cfg (feature = "ffmpeg_4_2" )] |
171 | Type::REGIONS_OF_INTEREST => AV_FRAME_DATA_REGIONS_OF_INTEREST, |
172 | |
173 | #[cfg (feature = "ffmpeg_4_3" )] |
174 | Type::VIDEO_ENC_PARAMS => AV_FRAME_DATA_VIDEO_ENC_PARAMS, |
175 | |
176 | #[cfg (feature = "ffmpeg_4_4" )] |
177 | Type::SEI_UNREGISTERED => AV_FRAME_DATA_SEI_UNREGISTERED, |
178 | #[cfg (feature = "ffmpeg_4_4" )] |
179 | Type::FILM_GRAIN_PARAMS => AV_FRAME_DATA_FILM_GRAIN_PARAMS, |
180 | |
181 | #[cfg (feature = "ffmpeg_5_0" )] |
182 | Type::DETECTION_BBOXES => AV_FRAME_DATA_DETECTION_BBOXES, |
183 | #[cfg (feature = "ffmpeg_5_0" )] |
184 | Type::DOVI_RPU_BUFFER => AV_FRAME_DATA_DOVI_RPU_BUFFER, |
185 | #[cfg (feature = "ffmpeg_5_0" )] |
186 | Type::DOVI_METADATA => AV_FRAME_DATA_DOVI_METADATA, |
187 | |
188 | #[cfg (feature = "ffmpeg_5_1" )] |
189 | Type::DYNAMIC_HDR_VIVID => AV_FRAME_DATA_DYNAMIC_HDR_VIVID, |
190 | |
191 | #[cfg (feature = "ffmpeg_6_0" )] |
192 | Type::AMBIENT_VIEWING_ENVIRONMENT => AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, |
193 | |
194 | #[cfg (feature = "ffmpeg_6_1" )] |
195 | Type::VIDEO_HINT => AV_FRAME_DATA_VIDEO_HINT, |
196 | } |
197 | } |
198 | } |
199 | |
200 | pub struct SideData<'a> { |
201 | ptr: *mut AVFrameSideData, |
202 | |
203 | _marker: PhantomData<&'a Frame>, |
204 | } |
205 | |
206 | impl<'a> SideData<'a> { |
207 | #[inline (always)] |
208 | pub unsafe fn wrap(ptr: *mut AVFrameSideData) -> Self { |
209 | SideData { |
210 | ptr, |
211 | _marker: PhantomData, |
212 | } |
213 | } |
214 | |
215 | #[inline (always)] |
216 | pub unsafe fn as_ptr(&self) -> *const AVFrameSideData { |
217 | self.ptr as *const _ |
218 | } |
219 | |
220 | #[inline (always)] |
221 | pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrameSideData { |
222 | self.ptr |
223 | } |
224 | } |
225 | |
226 | impl<'a> SideData<'a> { |
227 | #[inline ] |
228 | pub fn kind(&self) -> Type { |
229 | unsafe { Type::from((*self.as_ptr()).type_) } |
230 | } |
231 | |
232 | #[inline ] |
233 | pub fn data(&self) -> &[u8] { |
234 | #[allow (clippy::unnecessary_cast)] |
235 | unsafe { |
236 | slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize) |
237 | } |
238 | } |
239 | |
240 | #[inline ] |
241 | pub fn metadata(&self) -> DictionaryRef { |
242 | unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) } |
243 | } |
244 | } |
245 | |