gstreamer/
sample_serde.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use serde::{
4    de::{Deserialize, Deserializer},
5    ser::{Serialize, SerializeStruct, Serializer},
6};
7
8use crate::{Buffer, BufferList, Caps, Sample, SampleRef, Segment, Structure};
9
10impl Serialize for SampleRef {
11    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
12        let mut sample = serializer.serialize_struct("Sample", 5)?;
13        sample.serialize_field("buffer", &self.buffer())?;
14        sample.serialize_field("buffer_list", &self.buffer_list())?;
15        sample.serialize_field("caps", &self.caps())?;
16        sample.serialize_field("segment", &self.segment())?;
17        sample.serialize_field("info", &self.info())?;
18        sample.end()
19    }
20}
21
22impl Serialize for Sample {
23    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
24        self.as_ref().serialize(serializer)
25    }
26}
27
28#[derive(serde::Deserialize)]
29struct SampleDe {
30    buffer: Option<Buffer>,
31    buffer_list: Option<BufferList>,
32    caps: Option<Caps>,
33    segment: Option<Segment>,
34    info: Option<Structure>,
35}
36
37impl From<SampleDe> for Sample {
38    fn from(buf_de: SampleDe) -> Self {
39        skip_assert_initialized!();
40        let mut builder = Sample::builder();
41
42        if let Some(buffer) = buf_de.buffer.as_ref() {
43            builder = builder.buffer(buffer);
44        }
45
46        if let Some(buffer_list) = buf_de.buffer_list.as_ref() {
47            builder = builder.buffer_list(buffer_list);
48        }
49
50        if let Some(caps) = buf_de.caps.as_ref() {
51            builder = builder.caps(caps);
52        }
53
54        if let Some(segment) = buf_de.segment.as_ref() {
55            builder = builder.segment(segment);
56        }
57
58        if let Some(info) = buf_de.info {
59            builder = builder.info(info);
60        }
61
62        builder.build()
63    }
64}
65
66impl<'de> Deserialize<'de> for Sample {
67    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
68        skip_assert_initialized!();
69        SampleDe::deserialize(deserializer).map(|sample_de| sample_de.into())
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use crate::{
76        Buffer, Caps, ClockTime, Format, GenericFormattedValue, Sample, Segment, SegmentFlags,
77        Structure,
78    };
79
80    #[test]
81    fn test_serialize() {
82        crate::init().unwrap();
83
84        let pretty_config = ron::ser::PrettyConfig::new().new_line("".to_string());
85
86        let sample = {
87            let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
88            {
89                let buffer = buffer.get_mut().unwrap();
90                buffer.set_pts(Some(ClockTime::NSECOND));
91                buffer.set_offset(0);
92                buffer.set_offset_end(4);
93                buffer.set_duration(Some(4 * ClockTime::NSECOND));
94            }
95
96            let caps = Caps::builder("sample/caps")
97                .field("int", 12)
98                .field("bool", true)
99                .build();
100
101            let mut segment = Segment::new();
102            segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT);
103            segment.set_rate(1f64);
104            segment.set_applied_rate(0.9f64);
105            segment.set_format(Format::Time);
106            segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
107            segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
108            segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
109            segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
110            segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
111            segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
112            segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
113
114            let info = Structure::builder("sample.info")
115                .field("f3", 123i32)
116                .build();
117
118            Sample::builder()
119                .buffer(&buffer)
120                .caps(&caps)
121                .segment(&segment)
122                .info(info)
123                .build()
124        };
125
126        let res = ron::ser::to_string_pretty(&sample, pretty_config.clone());
127        assert_eq!(
128            Ok(concat!(
129                "(",
130                "    buffer: Some((",
131                "        pts: Some(1),",
132                "        dts: None,",
133                "        duration: Some(4),",
134                "        offset: 0,",
135                "        offset_end: 4,",
136                "        flags: \"\",",
137                "        buffer: b\"\\x01\\x02\\x03\\x04\",",
138                "    )),",
139                "    buffer_list: None,",
140                "    caps: Some(r#Some([",
141                "        ((\"sample/caps\", [",
142                "            (\"int\", \"i32\", 12),",
143                "            (\"bool\", \"bool\", true),",
144                "        ]), None),",
145                "    ])),",
146                "    segment: Some((",
147                "        flags: \"reset+segment\",",
148                "        rate: 1.0,",
149                "        applied_rate: 0.9,",
150                "        format: Time,",
151                "        base: 123,",
152                "        offset: 42,",
153                "        start: 1024,",
154                "        stop: 2048,",
155                "        time: 1042,",
156                "        position: 256,",
157                "        duration: -1,",
158                "    )),",
159                "    info: Some((\"sample.info\", [",
160                "        (\"f3\", \"i32\", 123),",
161                "    ])),",
162                ")"
163            )
164            .to_owned()),
165            res
166        );
167
168        let sample = {
169            let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
170            {
171                let buffer = buffer.get_mut().unwrap();
172                buffer.set_pts(Some(ClockTime::NSECOND));
173                buffer.set_offset(0);
174                buffer.set_offset_end(4);
175                buffer.set_duration(Some(4 * ClockTime::NSECOND));
176            }
177            Sample::builder().buffer(&buffer).build()
178        };
179
180        // `Sample`'s `Segment` is allocated in GStreamer 1.x, should be fixed in version 2.0
181
182        let res = ron::ser::to_string_pretty(&sample, pretty_config);
183        assert_eq!(
184            Ok(concat!(
185                "(",
186                "    buffer: Some((",
187                "        pts: Some(1),",
188                "        dts: None,",
189                "        duration: Some(4),",
190                "        offset: 0,",
191                "        offset_end: 4,",
192                "        flags: \"\",",
193                "        buffer: b\"\\x01\\x02\\x03\\x04\",",
194                "    )),",
195                "    buffer_list: None,",
196                "    caps: None,",
197                "    segment: Some((",
198                "        flags: \"\",",
199                "        rate: 1.0,",
200                "        applied_rate: 1.0,",
201                "        format: Time,",
202                "        base: 0,",
203                "        offset: 0,",
204                "        start: 0,",
205                "        stop: -1,",
206                "        time: 0,",
207                "        position: 0,",
208                "        duration: -1,",
209                "    )),",
210                "    info: None,",
211                ")"
212            )
213            .to_owned()),
214            res
215        );
216    }
217
218    #[test]
219    fn test_deserialize() {
220        crate::init().unwrap();
221
222        let buffer_ron = r#"
223            (
224                buffer: Some((
225                    pts: Some(1),
226                    dts: None,
227                    duration: Some(4),
228                    offset: 0,
229                    offset_end: 4,
230                    flags: "",
231                    buffer: b"\x01\x02\x03\x04",
232                )),
233                buffer_list: None,
234                caps: Some(Some([
235                    (("sample/caps", [
236                        ("int", "i32", 12),
237                        ("bool", "bool", true),
238                    ]), None),
239                ])),
240                segment: Some((
241                    flags: "",
242                    rate: 1,
243                    applied_rate: 0.9,
244                    format: Time,
245                    base: 123,
246                    offset: 42,
247                    start: 1024,
248                    stop: 2048,
249                    time: 1042,
250                    position: 256,
251                    duration: -1,
252                )),
253                info: Some(("sample.info", [
254                    ("f3", "i32", 123),
255                ])),
256            )"#;
257        let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
258        let buffer = sample.buffer().unwrap();
259        assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
260        assert_eq!(buffer.offset_end(), 4);
261        {
262            let data = buffer.map_readable().unwrap();
263            assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
264        }
265        assert!(sample.buffer_list().is_none());
266        assert!(sample.caps().is_some());
267        assert!(sample.segment().is_some());
268        assert!(sample.info().is_some());
269
270        let buffer_ron = r#"
271            (
272                buffer: None,
273                buffer_list: Some([
274                    (
275                        pts: Some(1),
276                        dts: None,
277                        duration: Some(4),
278                        offset: 0,
279                        offset_end: 4,
280                        flags: "",
281                        buffer: b"\x01\x02\x03\x04",
282                    ),
283                ]),
284                caps: None,
285                segment: None,
286                info: None,
287            )"#;
288        let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
289        assert!(sample.buffer().is_none());
290        assert!(sample.buffer_list().is_some());
291        assert!(sample.caps().is_none());
292        // Not true in GStreamer 1.x, should be fixed in version 2.0
293        //assert!(sample.get_segment().is_none());
294        assert!(sample.info().is_none());
295    }
296
297    #[test]
298    fn test_roundrip() {
299        crate::init().unwrap();
300
301        // Segment present
302        let sample = {
303            let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
304            {
305                let buffer = buffer.get_mut().unwrap();
306                buffer.set_pts(Some(ClockTime::NSECOND));
307                buffer.set_offset(0);
308                buffer.set_offset_end(4);
309                buffer.set_duration(Some(4 * ClockTime::NSECOND));
310            }
311
312            let caps = Caps::builder("sample/caps")
313                .field("int", 12)
314                .field("bool", true)
315                .build();
316
317            let mut segment = Segment::new();
318            segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT);
319            segment.set_rate(1f64);
320            segment.set_applied_rate(0.9f64);
321            segment.set_format(Format::Time);
322            segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
323            segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
324            segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
325            segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
326            segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
327            segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
328            segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
329
330            let info = Structure::builder("sample.info")
331                .field("f3", 123i32)
332                .build();
333
334            Sample::builder()
335                .buffer(&buffer)
336                .caps(&caps)
337                .segment(&segment)
338                .info(info)
339                .build()
340        };
341        let sample_ser = ron::ser::to_string(&sample).unwrap();
342        let sample_de: Sample = ron::de::from_str(sample_ser.as_str()).unwrap();
343        let buffer_de = sample_de.buffer().unwrap();
344        assert_eq!(buffer_de.pts(), Some(ClockTime::NSECOND));
345        assert_eq!(buffer_de.offset_end(), 4);
346        {
347            let data = buffer_de.map_readable().unwrap();
348            assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
349        }
350        assert!(sample_de.buffer_list().is_none());
351        assert!(sample_de.caps().is_some());
352        assert!(sample_de.segment().is_some());
353        assert!(sample_de.info().is_some());
354    }
355}