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