Skip to main content

ffmpeg_the_third/util/frame/
side_data.rs

1use std::marker::PhantomData;
2use std::slice;
3
4use super::Frame;
5use crate::ffi::*;
6use crate::utils;
7use crate::DictionaryRef;
8#[cfg(feature = "serialize")]
9use serde::{Deserialize, Serialize};
10
11#[derive(Eq, PartialEq, Copy, Clone, Debug)]
12#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
13pub enum Type {
14    PanScan,
15    A53CC,
16    Stereo3D,
17    MatrixEncoding,
18    DownMixInfo,
19    ReplayGain,
20    DisplayMatrix,
21    AFD,
22    MotionVectors,
23    SkipSamples,
24    AudioServiceType,
25    MasteringDisplayMetadata,
26    GOPTimecode,
27    Spherical,
28
29    ContentLightLevel,
30    IccProfile,
31
32    S12M_TIMECODE,
33
34    DYNAMIC_HDR_PLUS,
35    REGIONS_OF_INTEREST,
36
37    VIDEO_ENC_PARAMS,
38
39    SEI_UNREGISTERED,
40    FILM_GRAIN_PARAMS,
41
42    DETECTION_BBOXES,
43    DOVI_RPU_BUFFER,
44    DOVI_METADATA,
45
46    DYNAMIC_HDR_VIVID,
47
48    #[cfg(feature = "ffmpeg_6_0")]
49    AMBIENT_VIEWING_ENVIRONMENT,
50
51    #[cfg(feature = "ffmpeg_6_1")]
52    VIDEO_HINT,
53
54    #[cfg(feature = "ffmpeg_7_1")]
55    LCEVC,
56    #[cfg(feature = "ffmpeg_7_1")]
57    ViewId,
58
59    #[cfg(feature = "ffmpeg_8_0")]
60    _3DReferenceDisplays,
61
62    #[cfg(feature = "ffmpeg_8_1")]
63    EXIF,
64}
65
66impl Type {
67    #[inline]
68    pub fn name(&self) -> &'static str {
69        unsafe { utils::str_from_c_ptr(av_frame_side_data_name((*self).into())) }
70    }
71}
72
73impl From<AVFrameSideDataType> for Type {
74    #[inline(always)]
75    fn from(value: AVFrameSideDataType) -> Self {
76        use AVFrameSideDataType as AV;
77
78        match value {
79            AV::PANSCAN => Type::PanScan,
80            AV::A53_CC => Type::A53CC,
81            AV::STEREO3D => Type::Stereo3D,
82            AV::MATRIXENCODING => Type::MatrixEncoding,
83            AV::DOWNMIX_INFO => Type::DownMixInfo,
84            AV::REPLAYGAIN => Type::ReplayGain,
85            AV::DISPLAYMATRIX => Type::DisplayMatrix,
86            AV::AFD => Type::AFD,
87            AV::MOTION_VECTORS => Type::MotionVectors,
88            AV::SKIP_SAMPLES => Type::SkipSamples,
89            AV::AUDIO_SERVICE_TYPE => Type::AudioServiceType,
90            AV::MASTERING_DISPLAY_METADATA => Type::MasteringDisplayMetadata,
91            AV::GOP_TIMECODE => Type::GOPTimecode,
92            AV::SPHERICAL => Type::Spherical,
93
94            AV::CONTENT_LIGHT_LEVEL => Type::ContentLightLevel,
95            AV::ICC_PROFILE => Type::IccProfile,
96
97            AV::S12M_TIMECODE => Type::S12M_TIMECODE,
98
99            AV::DYNAMIC_HDR_PLUS => Type::DYNAMIC_HDR_PLUS,
100            AV::REGIONS_OF_INTEREST => Type::REGIONS_OF_INTEREST,
101
102            AV::VIDEO_ENC_PARAMS => Type::VIDEO_ENC_PARAMS,
103
104            AV::SEI_UNREGISTERED => Type::SEI_UNREGISTERED,
105            AV::FILM_GRAIN_PARAMS => Type::FILM_GRAIN_PARAMS,
106
107            AV::DETECTION_BBOXES => Type::DETECTION_BBOXES,
108            AV::DOVI_RPU_BUFFER => Type::DOVI_RPU_BUFFER,
109            AV::DOVI_METADATA => Type::DOVI_METADATA,
110
111            AV::DYNAMIC_HDR_VIVID => Type::DYNAMIC_HDR_VIVID,
112
113            #[cfg(feature = "ffmpeg_6_0")]
114            AV::AMBIENT_VIEWING_ENVIRONMENT => Type::AMBIENT_VIEWING_ENVIRONMENT,
115
116            #[cfg(feature = "ffmpeg_6_1")]
117            AV::VIDEO_HINT => Type::VIDEO_HINT,
118
119            #[cfg(feature = "ffmpeg_7_1")]
120            AV::LCEVC => Type::LCEVC,
121            #[cfg(feature = "ffmpeg_7_1")]
122            AV::VIEW_ID => Type::ViewId,
123
124            #[cfg(feature = "ffmpeg_8_0")]
125            AV::_3D_REFERENCE_DISPLAYS => Type::_3DReferenceDisplays,
126
127            #[cfg(feature = "ffmpeg_8_1")]
128            AV::EXIF => Type::EXIF,
129
130            _ => unimplemented!(),
131        }
132    }
133}
134
135impl From<Type> for AVFrameSideDataType {
136    #[inline(always)]
137    fn from(value: Type) -> AVFrameSideDataType {
138        use AVFrameSideDataType as AV;
139
140        match value {
141            Type::PanScan => AV::PANSCAN,
142            Type::A53CC => AV::A53_CC,
143            Type::Stereo3D => AV::STEREO3D,
144            Type::MatrixEncoding => AV::MATRIXENCODING,
145            Type::DownMixInfo => AV::DOWNMIX_INFO,
146            Type::ReplayGain => AV::REPLAYGAIN,
147            Type::DisplayMatrix => AV::DISPLAYMATRIX,
148            Type::AFD => AV::AFD,
149            Type::MotionVectors => AV::MOTION_VECTORS,
150            Type::SkipSamples => AV::SKIP_SAMPLES,
151            Type::AudioServiceType => AV::AUDIO_SERVICE_TYPE,
152            Type::MasteringDisplayMetadata => AV::MASTERING_DISPLAY_METADATA,
153            Type::GOPTimecode => AV::GOP_TIMECODE,
154            Type::Spherical => AV::SPHERICAL,
155
156            Type::ContentLightLevel => AV::CONTENT_LIGHT_LEVEL,
157            Type::IccProfile => AV::ICC_PROFILE,
158
159            Type::S12M_TIMECODE => AV::S12M_TIMECODE,
160
161            Type::DYNAMIC_HDR_PLUS => AV::DYNAMIC_HDR_PLUS,
162            Type::REGIONS_OF_INTEREST => AV::REGIONS_OF_INTEREST,
163
164            Type::VIDEO_ENC_PARAMS => AV::VIDEO_ENC_PARAMS,
165
166            Type::SEI_UNREGISTERED => AV::SEI_UNREGISTERED,
167            Type::FILM_GRAIN_PARAMS => AV::FILM_GRAIN_PARAMS,
168
169            Type::DETECTION_BBOXES => AV::DETECTION_BBOXES,
170            Type::DOVI_RPU_BUFFER => AV::DOVI_RPU_BUFFER,
171            Type::DOVI_METADATA => AV::DOVI_METADATA,
172
173            Type::DYNAMIC_HDR_VIVID => AV::DYNAMIC_HDR_VIVID,
174
175            #[cfg(feature = "ffmpeg_6_0")]
176            Type::AMBIENT_VIEWING_ENVIRONMENT => AV::AMBIENT_VIEWING_ENVIRONMENT,
177
178            #[cfg(feature = "ffmpeg_6_1")]
179            Type::VIDEO_HINT => AV::VIDEO_HINT,
180
181            #[cfg(feature = "ffmpeg_7_1")]
182            Type::LCEVC => AV::LCEVC,
183            #[cfg(feature = "ffmpeg_7_1")]
184            Type::ViewId => AV::VIEW_ID,
185
186            #[cfg(feature = "ffmpeg_8_0")]
187            Type::_3DReferenceDisplays => AV::_3D_REFERENCE_DISPLAYS,
188
189            #[cfg(feature = "ffmpeg_8_1")]
190            Type::EXIF => AV::EXIF,
191        }
192    }
193}
194
195pub struct SideData<'a> {
196    ptr: *mut AVFrameSideData,
197
198    _marker: PhantomData<&'a Frame>,
199}
200
201impl<'a> SideData<'a> {
202    #[inline(always)]
203    pub unsafe fn wrap(ptr: *mut AVFrameSideData) -> Self {
204        SideData {
205            ptr,
206            _marker: PhantomData,
207        }
208    }
209
210    #[inline(always)]
211    pub unsafe fn as_ptr(&self) -> *const AVFrameSideData {
212        self.ptr as *const _
213    }
214
215    #[inline(always)]
216    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrameSideData {
217        self.ptr
218    }
219}
220
221impl<'a> SideData<'a> {
222    #[inline]
223    pub fn kind(&self) -> Type {
224        unsafe { Type::from((*self.as_ptr()).type_) }
225    }
226
227    #[inline]
228    pub fn data(&self) -> &[u8] {
229        unsafe { slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize) }
230    }
231
232    pub fn metadata(&self) -> DictionaryRef<'_> {
233        unsafe { DictionaryRef::from_raw((*self.as_ptr()).metadata) }
234    }
235}