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