Skip to main content

ffmpeg_next/util/frame/
side_data.rs

1use std::ffi::CStr;
2use std::marker::PhantomData;
3use std::slice;
4use std::str::from_utf8_unchecked;
5
6use super::Frame;
7use crate::DictionaryRef;
8use crate::ffi::AVFrameSideDataType::*;
9use crate::ffi::*;
10
11#[derive(Eq, PartialEq, Copy, Clone, Debug)]
12pub 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    #[cfg(feature = "ffmpeg_8_0")]
74    THREE_D_REFERENCE_DISPLAYS,
75
76    #[cfg(feature = "ffmpeg_8_1")]
77    EXIF,
78
79    #[cfg(feature = "ffmpeg_9_0")]
80    DYNAMIC_HDR_SMPTE_2094_APP5,
81    #[cfg(feature = "ffmpeg_9_0")]
82    IAMF_MIX_GAIN_PARAM,
83    #[cfg(feature = "ffmpeg_9_0")]
84    IAMF_DEMIXING_INFO_PARAM,
85    #[cfg(feature = "ffmpeg_9_0")]
86    IAMF_RECON_GAIN_INFO_PARAM,
87    #[cfg(feature = "ffmpeg_9_0")]
88    RAW_COLOR_PARAMS,
89}
90
91impl Type {
92    #[inline]
93    pub fn name(&self) -> &'static str {
94        unsafe {
95            from_utf8_unchecked(CStr::from_ptr(av_frame_side_data_name((*self).into())).to_bytes())
96        }
97    }
98}
99
100impl From<AVFrameSideDataType> for Type {
101    #[inline(always)]
102    fn from(value: AVFrameSideDataType) -> Self {
103        match value {
104            AV_FRAME_DATA_PANSCAN => Type::PanScan,
105            AV_FRAME_DATA_A53_CC => Type::A53CC,
106            AV_FRAME_DATA_STEREO3D => Type::Stereo3D,
107            AV_FRAME_DATA_MATRIXENCODING => Type::MatrixEncoding,
108            AV_FRAME_DATA_DOWNMIX_INFO => Type::DownMixInfo,
109            AV_FRAME_DATA_REPLAYGAIN => Type::ReplayGain,
110            AV_FRAME_DATA_DISPLAYMATRIX => Type::DisplayMatrix,
111            AV_FRAME_DATA_AFD => Type::AFD,
112            AV_FRAME_DATA_MOTION_VECTORS => Type::MotionVectors,
113            AV_FRAME_DATA_SKIP_SAMPLES => Type::SkipSamples,
114            AV_FRAME_DATA_AUDIO_SERVICE_TYPE => Type::AudioServiceType,
115            AV_FRAME_DATA_MASTERING_DISPLAY_METADATA => Type::MasteringDisplayMetadata,
116            AV_FRAME_DATA_GOP_TIMECODE => Type::GOPTimecode,
117            AV_FRAME_DATA_SPHERICAL => Type::Spherical,
118
119            AV_FRAME_DATA_CONTENT_LIGHT_LEVEL => Type::ContentLightLevel,
120            AV_FRAME_DATA_ICC_PROFILE => Type::IccProfile,
121
122            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
123            AV_FRAME_DATA_QP_TABLE_PROPERTIES => Type::QPTableProperties,
124            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
125            AV_FRAME_DATA_QP_TABLE_DATA => Type::QPTableData,
126            #[cfg(feature = "ffmpeg_4_1")]
127            AV_FRAME_DATA_S12M_TIMECODE => Type::S12M_TIMECODE,
128
129            #[cfg(feature = "ffmpeg_4_2")]
130            AV_FRAME_DATA_DYNAMIC_HDR_PLUS => Type::DYNAMIC_HDR_PLUS,
131            #[cfg(feature = "ffmpeg_4_2")]
132            AV_FRAME_DATA_REGIONS_OF_INTEREST => Type::REGIONS_OF_INTEREST,
133
134            #[cfg(feature = "ffmpeg_4_3")]
135            AV_FRAME_DATA_VIDEO_ENC_PARAMS => Type::VIDEO_ENC_PARAMS,
136
137            #[cfg(feature = "ffmpeg_4_4")]
138            AV_FRAME_DATA_SEI_UNREGISTERED => Type::SEI_UNREGISTERED,
139            #[cfg(feature = "ffmpeg_4_4")]
140            AV_FRAME_DATA_FILM_GRAIN_PARAMS => Type::FILM_GRAIN_PARAMS,
141
142            #[cfg(feature = "ffmpeg_5_0")]
143            AV_FRAME_DATA_DETECTION_BBOXES => Type::DETECTION_BBOXES,
144            #[cfg(feature = "ffmpeg_5_0")]
145            AV_FRAME_DATA_DOVI_RPU_BUFFER => Type::DOVI_RPU_BUFFER,
146            #[cfg(feature = "ffmpeg_5_0")]
147            AV_FRAME_DATA_DOVI_METADATA => Type::DOVI_METADATA,
148
149            #[cfg(feature = "ffmpeg_5_1")]
150            AV_FRAME_DATA_DYNAMIC_HDR_VIVID => Type::DYNAMIC_HDR_VIVID,
151
152            #[cfg(feature = "ffmpeg_6_0")]
153            AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT => Type::AMBIENT_VIEWING_ENVIRONMENT,
154
155            #[cfg(feature = "ffmpeg_6_1")]
156            AV_FRAME_DATA_VIDEO_HINT => Type::VIDEO_HINT,
157
158            #[cfg(feature = "ffmpeg_7_1")]
159            AV_FRAME_DATA_LCEVC => Type::LCEVC,
160            #[cfg(feature = "ffmpeg_7_1")]
161            AV_FRAME_DATA_VIEW_ID => Type::VIEW_ID,
162
163            #[cfg(feature = "ffmpeg_8_0")]
164            AV_FRAME_DATA_3D_REFERENCE_DISPLAYS => Type::THREE_D_REFERENCE_DISPLAYS,
165
166            #[cfg(feature = "ffmpeg_8_1")]
167            AV_FRAME_DATA_EXIF => Type::EXIF,
168
169            #[cfg(feature = "ffmpeg_9_0")]
170            AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5 => Type::DYNAMIC_HDR_SMPTE_2094_APP5,
171            #[cfg(feature = "ffmpeg_9_0")]
172            AV_FRAME_DATA_IAMF_MIX_GAIN_PARAM => Type::IAMF_MIX_GAIN_PARAM,
173            #[cfg(feature = "ffmpeg_9_0")]
174            AV_FRAME_DATA_IAMF_DEMIXING_INFO_PARAM => Type::IAMF_DEMIXING_INFO_PARAM,
175            #[cfg(feature = "ffmpeg_9_0")]
176            AV_FRAME_DATA_IAMF_RECON_GAIN_INFO_PARAM => Type::IAMF_RECON_GAIN_INFO_PARAM,
177            #[cfg(feature = "ffmpeg_9_0")]
178            AV_FRAME_DATA_RAW_COLOR_PARAMS => Type::RAW_COLOR_PARAMS,
179
180            #[cfg(feature = "non-exhaustive-enums")]
181            _ => unimplemented!(),
182        }
183    }
184}
185
186impl From<Type> for AVFrameSideDataType {
187    #[inline(always)]
188    fn from(value: Type) -> AVFrameSideDataType {
189        match value {
190            Type::PanScan => AV_FRAME_DATA_PANSCAN,
191            Type::A53CC => AV_FRAME_DATA_A53_CC,
192            Type::Stereo3D => AV_FRAME_DATA_STEREO3D,
193            Type::MatrixEncoding => AV_FRAME_DATA_MATRIXENCODING,
194            Type::DownMixInfo => AV_FRAME_DATA_DOWNMIX_INFO,
195            Type::ReplayGain => AV_FRAME_DATA_REPLAYGAIN,
196            Type::DisplayMatrix => AV_FRAME_DATA_DISPLAYMATRIX,
197            Type::AFD => AV_FRAME_DATA_AFD,
198            Type::MotionVectors => AV_FRAME_DATA_MOTION_VECTORS,
199            Type::SkipSamples => AV_FRAME_DATA_SKIP_SAMPLES,
200            Type::AudioServiceType => AV_FRAME_DATA_AUDIO_SERVICE_TYPE,
201            Type::MasteringDisplayMetadata => AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
202            Type::GOPTimecode => AV_FRAME_DATA_GOP_TIMECODE,
203            Type::Spherical => AV_FRAME_DATA_SPHERICAL,
204
205            Type::ContentLightLevel => AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
206            Type::IccProfile => AV_FRAME_DATA_ICC_PROFILE,
207
208            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
209            Type::QPTableProperties => AV_FRAME_DATA_QP_TABLE_PROPERTIES,
210            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
211            Type::QPTableData => AV_FRAME_DATA_QP_TABLE_DATA,
212            #[cfg(feature = "ffmpeg_4_1")]
213            Type::S12M_TIMECODE => AV_FRAME_DATA_S12M_TIMECODE,
214
215            #[cfg(feature = "ffmpeg_4_2")]
216            Type::DYNAMIC_HDR_PLUS => AV_FRAME_DATA_DYNAMIC_HDR_PLUS,
217            #[cfg(feature = "ffmpeg_4_2")]
218            Type::REGIONS_OF_INTEREST => AV_FRAME_DATA_REGIONS_OF_INTEREST,
219
220            #[cfg(feature = "ffmpeg_4_3")]
221            Type::VIDEO_ENC_PARAMS => AV_FRAME_DATA_VIDEO_ENC_PARAMS,
222
223            #[cfg(feature = "ffmpeg_4_4")]
224            Type::SEI_UNREGISTERED => AV_FRAME_DATA_SEI_UNREGISTERED,
225            #[cfg(feature = "ffmpeg_4_4")]
226            Type::FILM_GRAIN_PARAMS => AV_FRAME_DATA_FILM_GRAIN_PARAMS,
227
228            #[cfg(feature = "ffmpeg_5_0")]
229            Type::DETECTION_BBOXES => AV_FRAME_DATA_DETECTION_BBOXES,
230            #[cfg(feature = "ffmpeg_5_0")]
231            Type::DOVI_RPU_BUFFER => AV_FRAME_DATA_DOVI_RPU_BUFFER,
232            #[cfg(feature = "ffmpeg_5_0")]
233            Type::DOVI_METADATA => AV_FRAME_DATA_DOVI_METADATA,
234
235            #[cfg(feature = "ffmpeg_5_1")]
236            Type::DYNAMIC_HDR_VIVID => AV_FRAME_DATA_DYNAMIC_HDR_VIVID,
237
238            #[cfg(feature = "ffmpeg_6_0")]
239            Type::AMBIENT_VIEWING_ENVIRONMENT => AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT,
240
241            #[cfg(feature = "ffmpeg_6_1")]
242            Type::VIDEO_HINT => AV_FRAME_DATA_VIDEO_HINT,
243
244            #[cfg(feature = "ffmpeg_7_1")]
245            Type::LCEVC => AV_FRAME_DATA_LCEVC,
246            #[cfg(feature = "ffmpeg_7_1")]
247            Type::VIEW_ID => AV_FRAME_DATA_VIEW_ID,
248
249            #[cfg(feature = "ffmpeg_8_0")]
250            Type::THREE_D_REFERENCE_DISPLAYS => AV_FRAME_DATA_3D_REFERENCE_DISPLAYS,
251
252            #[cfg(feature = "ffmpeg_8_1")]
253            Type::EXIF => AV_FRAME_DATA_EXIF,
254
255            #[cfg(feature = "ffmpeg_9_0")]
256            Type::DYNAMIC_HDR_SMPTE_2094_APP5 => AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5,
257            #[cfg(feature = "ffmpeg_9_0")]
258            Type::IAMF_MIX_GAIN_PARAM => AV_FRAME_DATA_IAMF_MIX_GAIN_PARAM,
259            #[cfg(feature = "ffmpeg_9_0")]
260            Type::IAMF_DEMIXING_INFO_PARAM => AV_FRAME_DATA_IAMF_DEMIXING_INFO_PARAM,
261            #[cfg(feature = "ffmpeg_9_0")]
262            Type::IAMF_RECON_GAIN_INFO_PARAM => AV_FRAME_DATA_IAMF_RECON_GAIN_INFO_PARAM,
263            #[cfg(feature = "ffmpeg_9_0")]
264            Type::RAW_COLOR_PARAMS => AV_FRAME_DATA_RAW_COLOR_PARAMS,
265        }
266    }
267}
268
269pub struct SideData<'a> {
270    ptr: *mut AVFrameSideData,
271
272    _marker: PhantomData<&'a Frame>,
273}
274
275impl<'a> SideData<'a> {
276    #[inline(always)]
277    pub unsafe fn wrap(ptr: *mut AVFrameSideData) -> Self {
278        SideData {
279            ptr,
280            _marker: PhantomData,
281        }
282    }
283
284    #[inline(always)]
285    pub unsafe fn as_ptr(&self) -> *const AVFrameSideData {
286        self.ptr as *const _
287    }
288
289    #[inline(always)]
290    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrameSideData {
291        self.ptr
292    }
293}
294
295impl<'a> SideData<'a> {
296    #[inline]
297    pub fn kind(&self) -> Type {
298        unsafe { Type::from((*self.as_ptr()).type_) }
299    }
300
301    #[inline]
302    pub fn data(&self) -> &[u8] {
303        #[allow(clippy::unnecessary_cast)]
304        unsafe {
305            slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize)
306        }
307    }
308
309    #[inline]
310    pub fn metadata(&self) -> DictionaryRef<'_> {
311        unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) }
312    }
313}