playa_ffmpeg/util/frame/
side_data.rs

1use std::{ffi::CStr, marker::PhantomData, slice, str::from_utf8_unchecked};
2
3use super::Frame;
4use crate::{
5    DictionaryRef,
6    ffi::{AVFrameSideDataType::*, *},
7};
8
9#[derive(Eq, PartialEq, Copy, Clone, Debug)]
10pub enum Type {
11    PanScan,
12    A53CC,
13    Stereo3D,
14    MatrixEncoding,
15    DownMixInfo,
16    ReplayGain,
17    DisplayMatrix,
18    AFD,
19    MotionVectors,
20    SkipSamples,
21    AudioServiceType,
22    MasteringDisplayMetadata,
23    GOPTimecode,
24    Spherical,
25
26    ContentLightLevel,
27    IccProfile,
28
29    #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
30    QPTableProperties,
31    #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
32    QPTableData,
33
34    #[cfg(feature = "ffmpeg_4_1")]
35    S12M_TIMECODE,
36
37    #[cfg(feature = "ffmpeg_4_2")]
38    DYNAMIC_HDR_PLUS,
39    #[cfg(feature = "ffmpeg_4_2")]
40    REGIONS_OF_INTEREST,
41
42    #[cfg(feature = "ffmpeg_4_3")]
43    VIDEO_ENC_PARAMS,
44
45    #[cfg(feature = "ffmpeg_4_4")]
46    SEI_UNREGISTERED,
47    #[cfg(feature = "ffmpeg_4_4")]
48    FILM_GRAIN_PARAMS,
49
50    #[cfg(feature = "ffmpeg_5_0")]
51    DETECTION_BBOXES,
52    #[cfg(feature = "ffmpeg_5_0")]
53    DOVI_RPU_BUFFER,
54    #[cfg(feature = "ffmpeg_5_0")]
55    DOVI_METADATA,
56
57    #[cfg(feature = "ffmpeg_5_1")]
58    DYNAMIC_HDR_VIVID,
59
60    #[cfg(feature = "ffmpeg_6_0")]
61    AMBIENT_VIEWING_ENVIRONMENT,
62
63    #[cfg(feature = "ffmpeg_6_1")]
64    VIDEO_HINT,
65
66    #[cfg(feature = "ffmpeg_7_1")]
67    LCEVC,
68    #[cfg(feature = "ffmpeg_7_1")]
69    VIEW_ID,
70
71    #[cfg(feature = "ffmpeg_8_0")]
72    THREE_D_REFERENCE_DISPLAYS,
73}
74
75impl Type {
76    #[inline]
77    pub fn name(&self) -> &'static str {
78        unsafe { from_utf8_unchecked(CStr::from_ptr(av_frame_side_data_name((*self).into())).to_bytes()) }
79    }
80}
81
82impl From<AVFrameSideDataType> for Type {
83    #[inline(always)]
84    fn from(value: AVFrameSideDataType) -> Self {
85        match value {
86            AV_FRAME_DATA_PANSCAN => Type::PanScan,
87            AV_FRAME_DATA_A53_CC => Type::A53CC,
88            AV_FRAME_DATA_STEREO3D => Type::Stereo3D,
89            AV_FRAME_DATA_MATRIXENCODING => Type::MatrixEncoding,
90            AV_FRAME_DATA_DOWNMIX_INFO => Type::DownMixInfo,
91            AV_FRAME_DATA_REPLAYGAIN => Type::ReplayGain,
92            AV_FRAME_DATA_DISPLAYMATRIX => Type::DisplayMatrix,
93            AV_FRAME_DATA_AFD => Type::AFD,
94            AV_FRAME_DATA_MOTION_VECTORS => Type::MotionVectors,
95            AV_FRAME_DATA_SKIP_SAMPLES => Type::SkipSamples,
96            AV_FRAME_DATA_AUDIO_SERVICE_TYPE => Type::AudioServiceType,
97            AV_FRAME_DATA_MASTERING_DISPLAY_METADATA => Type::MasteringDisplayMetadata,
98            AV_FRAME_DATA_GOP_TIMECODE => Type::GOPTimecode,
99            AV_FRAME_DATA_SPHERICAL => Type::Spherical,
100
101            AV_FRAME_DATA_CONTENT_LIGHT_LEVEL => Type::ContentLightLevel,
102            AV_FRAME_DATA_ICC_PROFILE => Type::IccProfile,
103
104            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
105            AV_FRAME_DATA_QP_TABLE_PROPERTIES => Type::QPTableProperties,
106            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
107            AV_FRAME_DATA_QP_TABLE_DATA => Type::QPTableData,
108            #[cfg(feature = "ffmpeg_4_1")]
109            AV_FRAME_DATA_S12M_TIMECODE => Type::S12M_TIMECODE,
110
111            #[cfg(feature = "ffmpeg_4_2")]
112            AV_FRAME_DATA_DYNAMIC_HDR_PLUS => Type::DYNAMIC_HDR_PLUS,
113            #[cfg(feature = "ffmpeg_4_2")]
114            AV_FRAME_DATA_REGIONS_OF_INTEREST => Type::REGIONS_OF_INTEREST,
115
116            #[cfg(feature = "ffmpeg_4_3")]
117            AV_FRAME_DATA_VIDEO_ENC_PARAMS => Type::VIDEO_ENC_PARAMS,
118
119            #[cfg(feature = "ffmpeg_4_4")]
120            AV_FRAME_DATA_SEI_UNREGISTERED => Type::SEI_UNREGISTERED,
121            #[cfg(feature = "ffmpeg_4_4")]
122            AV_FRAME_DATA_FILM_GRAIN_PARAMS => Type::FILM_GRAIN_PARAMS,
123
124            #[cfg(feature = "ffmpeg_5_0")]
125            AV_FRAME_DATA_DETECTION_BBOXES => Type::DETECTION_BBOXES,
126            #[cfg(feature = "ffmpeg_5_0")]
127            AV_FRAME_DATA_DOVI_RPU_BUFFER => Type::DOVI_RPU_BUFFER,
128            #[cfg(feature = "ffmpeg_5_0")]
129            AV_FRAME_DATA_DOVI_METADATA => Type::DOVI_METADATA,
130
131            #[cfg(feature = "ffmpeg_5_1")]
132            AV_FRAME_DATA_DYNAMIC_HDR_VIVID => Type::DYNAMIC_HDR_VIVID,
133
134            #[cfg(feature = "ffmpeg_6_0")]
135            AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT => Type::AMBIENT_VIEWING_ENVIRONMENT,
136
137            #[cfg(feature = "ffmpeg_6_1")]
138            AV_FRAME_DATA_VIDEO_HINT => Type::VIDEO_HINT,
139
140            #[cfg(feature = "ffmpeg_7_1")]
141            AV_FRAME_DATA_LCEVC => Type::LCEVC,
142            #[cfg(feature = "ffmpeg_7_1")]
143            AV_FRAME_DATA_VIEW_ID => Type::VIEW_ID,
144
145            #[cfg(feature = "ffmpeg_8_0")]
146            AV_FRAME_DATA_3D_REFERENCE_DISPLAYS => Type::THREE_D_REFERENCE_DISPLAYS,
147        }
148    }
149}
150
151impl From<Type> for AVFrameSideDataType {
152    #[inline(always)]
153    fn from(value: Type) -> AVFrameSideDataType {
154        match value {
155            Type::PanScan => AV_FRAME_DATA_PANSCAN,
156            Type::A53CC => AV_FRAME_DATA_A53_CC,
157            Type::Stereo3D => AV_FRAME_DATA_STEREO3D,
158            Type::MatrixEncoding => AV_FRAME_DATA_MATRIXENCODING,
159            Type::DownMixInfo => AV_FRAME_DATA_DOWNMIX_INFO,
160            Type::ReplayGain => AV_FRAME_DATA_REPLAYGAIN,
161            Type::DisplayMatrix => AV_FRAME_DATA_DISPLAYMATRIX,
162            Type::AFD => AV_FRAME_DATA_AFD,
163            Type::MotionVectors => AV_FRAME_DATA_MOTION_VECTORS,
164            Type::SkipSamples => AV_FRAME_DATA_SKIP_SAMPLES,
165            Type::AudioServiceType => AV_FRAME_DATA_AUDIO_SERVICE_TYPE,
166            Type::MasteringDisplayMetadata => AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
167            Type::GOPTimecode => AV_FRAME_DATA_GOP_TIMECODE,
168            Type::Spherical => AV_FRAME_DATA_SPHERICAL,
169
170            Type::ContentLightLevel => AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
171            Type::IccProfile => AV_FRAME_DATA_ICC_PROFILE,
172
173            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
174            Type::QPTableProperties => AV_FRAME_DATA_QP_TABLE_PROPERTIES,
175            #[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
176            Type::QPTableData => AV_FRAME_DATA_QP_TABLE_DATA,
177            #[cfg(feature = "ffmpeg_4_1")]
178            Type::S12M_TIMECODE => AV_FRAME_DATA_S12M_TIMECODE,
179
180            #[cfg(feature = "ffmpeg_4_2")]
181            Type::DYNAMIC_HDR_PLUS => AV_FRAME_DATA_DYNAMIC_HDR_PLUS,
182            #[cfg(feature = "ffmpeg_4_2")]
183            Type::REGIONS_OF_INTEREST => AV_FRAME_DATA_REGIONS_OF_INTEREST,
184
185            #[cfg(feature = "ffmpeg_4_3")]
186            Type::VIDEO_ENC_PARAMS => AV_FRAME_DATA_VIDEO_ENC_PARAMS,
187
188            #[cfg(feature = "ffmpeg_4_4")]
189            Type::SEI_UNREGISTERED => AV_FRAME_DATA_SEI_UNREGISTERED,
190            #[cfg(feature = "ffmpeg_4_4")]
191            Type::FILM_GRAIN_PARAMS => AV_FRAME_DATA_FILM_GRAIN_PARAMS,
192
193            #[cfg(feature = "ffmpeg_5_0")]
194            Type::DETECTION_BBOXES => AV_FRAME_DATA_DETECTION_BBOXES,
195            #[cfg(feature = "ffmpeg_5_0")]
196            Type::DOVI_RPU_BUFFER => AV_FRAME_DATA_DOVI_RPU_BUFFER,
197            #[cfg(feature = "ffmpeg_5_0")]
198            Type::DOVI_METADATA => AV_FRAME_DATA_DOVI_METADATA,
199
200            #[cfg(feature = "ffmpeg_5_1")]
201            Type::DYNAMIC_HDR_VIVID => AV_FRAME_DATA_DYNAMIC_HDR_VIVID,
202
203            #[cfg(feature = "ffmpeg_6_0")]
204            Type::AMBIENT_VIEWING_ENVIRONMENT => AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT,
205
206            #[cfg(feature = "ffmpeg_6_1")]
207            Type::VIDEO_HINT => AV_FRAME_DATA_VIDEO_HINT,
208
209            #[cfg(feature = "ffmpeg_7_1")]
210            Type::LCEVC => AV_FRAME_DATA_LCEVC,
211            #[cfg(feature = "ffmpeg_7_1")]
212            Type::VIEW_ID => AV_FRAME_DATA_VIEW_ID,
213
214            #[cfg(feature = "ffmpeg_8_0")]
215            Type::THREE_D_REFERENCE_DISPLAYS => AV_FRAME_DATA_3D_REFERENCE_DISPLAYS,
216        }
217    }
218}
219
220pub struct SideData<'a> {
221    ptr: *mut AVFrameSideData,
222
223    _marker: PhantomData<&'a Frame>,
224}
225
226impl<'a> SideData<'a> {
227    #[inline(always)]
228    pub unsafe fn wrap(ptr: *mut AVFrameSideData) -> Self {
229        SideData { ptr, _marker: PhantomData }
230    }
231
232    #[inline(always)]
233    pub unsafe fn as_ptr(&self) -> *const AVFrameSideData {
234        self.ptr as *const _
235    }
236
237    #[inline(always)]
238    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrameSideData {
239        self.ptr
240    }
241}
242
243impl<'a> SideData<'a> {
244    #[inline]
245    pub fn kind(&self) -> Type {
246        unsafe { Type::from((*self.as_ptr()).type_) }
247    }
248
249    #[inline]
250    pub fn data(&self) -> &[u8] {
251        #[allow(clippy::unnecessary_cast)]
252        unsafe {
253            slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize)
254        }
255    }
256
257    #[inline]
258    pub fn metadata(&self) -> DictionaryRef<'_> {
259        unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) }
260    }
261}