1use bitfield_struct::bitfield;
2use bytes::Bytes;
3
4#[bitfield(u8, order = Msb)]
5pub struct AdaptationFieldFlags {
6 pub discontinuity_indicator: bool,
7 pub random_access_indicator: bool,
8 pub elementary_stream_priority_indicator: bool,
9 pub pcr_flag: bool,
10 pub opcr_flag: bool,
11 pub splicing_point_flag: bool,
12 pub transport_private_data_flag: bool,
13 pub adaptation_field_extension_flag: bool,
14}
15
16#[derive(Debug)]
17pub struct AdaptationField {
18 pub adaptation_field_length: u8,
19 pub flags: AdaptationFieldFlags,
20 pub program_clock_reference: Option<u64>, pub original_program_clock_reference: Option<u64>, pub splice_countdown: Option<u8>,
25 pub transport_private_data: Bytes,
27 pub adaptation_field_extension: Bytes,
29 }
31
32impl AdaptationField {
33 pub fn from_bytes(data: Bytes) -> Option<Self> {
35 let adaption_field_length = data.len();
36 let mut index = 0;
37 let flags = AdaptationFieldFlags::from_bits(*data.get(index)?);
38 index += 1;
39
40 let program_clock_reference = if flags.pcr_flag() {
41 let pcr_bytes = data.get(index..index + 6)?;
42 let pcr_base = (u32::from_be_bytes(pcr_bytes[0..4].try_into().unwrap()) as u64) << 1
43 | (pcr_bytes[4] >> 7) as u64; let pcr_extension = ((pcr_bytes[4] as u64) & 1) << 8 | pcr_bytes[5] as u64; index += 6;
46 Some(pcr_base * 300 + pcr_extension)
47 } else {
48 None
49 };
50 let original_program_clock_reference = if flags.opcr_flag() {
51 let opcr_bytes = data.get(index..index + 6)?;
52 let opcr_base = (u32::from_be_bytes(opcr_bytes[0..4].try_into().unwrap()) as u64) << 1
53 | (opcr_bytes[4] >> 7) as u64; let opcr_extension = ((opcr_bytes[4] as u64) & 1) << 8 | opcr_bytes[5] as u64; index += 6;
56 Some(opcr_base * 300 + opcr_extension)
57 } else {
58 None
59 };
60 let splice_countdown = if flags.splicing_point_flag() {
61 let countdown = *data.get(index)?;
62 index += 1;
63 Some(countdown)
64 } else {
65 None
66 };
67 let transport_private_data = if flags.transport_private_data_flag() {
68 let len = *data.get(index)? as usize;
69 index += 1;
70 if index + len > data.len() {
71 return None;
72 }
73 let slice = data.slice(index..index + len);
74 index += len;
75 slice
76 } else {
77 Bytes::new()
78 };
79 let adaptation_field_extension = if flags.adaptation_field_extension_flag() {
80 let len = *data.get(index)? as usize;
81 index += 1;
82 if index + len > data.len() {
83 return None;
84 }
85 let slice = data.slice(index..index + len);
86 slice
88 } else {
89 Bytes::new()
90 };
91 Some(Self {
92 adaptation_field_length: adaption_field_length as u8,
93 flags,
94 program_clock_reference,
95 original_program_clock_reference,
96 splice_countdown,
97 transport_private_data,
98 adaptation_field_extension,
99 })
100 }
101 pub fn to_bytes(&self) -> Vec<u8> {
102 let mut data = Vec::with_capacity(self.adaptation_field_length as usize);
103 data.push(self.flags.into_bits());
104 if self.flags.pcr_flag() {
105 let pcr_base = self.program_clock_reference.unwrap() / 300;
106 let pcr_extension = self.program_clock_reference.unwrap() % 300;
107 let pcr_bytes = [
108 (pcr_base >> 25) as u8,
109 (pcr_base >> 17) as u8,
110 (pcr_base >> 9) as u8,
111 (pcr_base >> 1) as u8,
112 ((pcr_base & 1) << 7) as u8 | 0x7E | (pcr_extension >> 8) as u8,
113 (pcr_extension & 0xFF) as u8,
114 ];
115 data.extend_from_slice(&pcr_bytes);
116 }
117 if self.flags.opcr_flag() {
118 let opcr_base = self.original_program_clock_reference.unwrap() / 300;
119 let opcr_extension = self.original_program_clock_reference.unwrap() % 300;
120 let opcr_bytes = [
121 (opcr_base >> 25) as u8,
122 (opcr_base >> 17) as u8,
123 (opcr_base >> 9) as u8,
124 (opcr_base >> 1) as u8,
125 ((opcr_base & 1) << 7) as u8 | 0x7E | (opcr_extension >> 8) as u8,
126 (opcr_extension & 0xFF) as u8,
127 ];
128 data.extend_from_slice(&opcr_bytes);
129 }
130 if self.flags.splicing_point_flag() {
131 data.push(self.splice_countdown.unwrap_or_default());
132 }
133 if self.flags.transport_private_data_flag() {
134 data.push(self.transport_private_data.len() as u8);
135 data.extend_from_slice(&self.transport_private_data);
136 }
137 if self.flags.adaptation_field_extension_flag() {
138 data.push(self.adaptation_field_extension.len() as u8);
139 data.extend_from_slice(&self.adaptation_field_extension);
140 }
141
142 while data.len() < self.adaptation_field_length as usize {
144 data.push(0xFF);
145 }
146 data
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[allow(clippy::too_many_arguments)]
155 fn make_flags(
157 discontinuity: bool,
158 random_access: bool,
159 es_priority: bool,
160 pcr: bool,
161 opcr: bool,
162 splicing: bool,
163 private_data: bool,
164 extension: bool,
165 ) -> u8 {
166 (discontinuity as u8) << 7
167 | (random_access as u8) << 6
168 | (es_priority as u8) << 5
169 | (pcr as u8) << 4
170 | (opcr as u8) << 3
171 | (splicing as u8) << 2
172 | (private_data as u8) << 1
173 | extension as u8
174 }
175
176 fn encode_pcr(base: u64, extension: u64) -> [u8; 6] {
178 [
179 (base >> 25) as u8,
180 (base >> 17) as u8,
181 (base >> 9) as u8,
182 (base >> 1) as u8,
183 ((base & 1) << 7) as u8 | 0x7E | (extension >> 8) as u8,
184 (extension & 0xFF) as u8,
185 ]
186 }
187
188 #[test]
193 fn test_flags_only_no_optional_fields() {
194 let data = Bytes::from_static(&[0x00]);
196 let af = AdaptationField::from_bytes(data).unwrap();
197 assert_eq!(af.adaptation_field_length, 1);
198 assert!(af.program_clock_reference.is_none());
199 assert!(af.original_program_clock_reference.is_none());
200 assert!(af.splice_countdown.is_none());
201 assert!(af.transport_private_data.is_empty());
202 assert!(af.adaptation_field_extension.is_empty());
203 }
204
205 #[test]
206 fn test_pcr_decode_zero() {
207 let flags = make_flags(false, false, false, true, false, false, false, false);
209 let pcr = encode_pcr(0, 0);
210 let mut data = vec![flags];
211 data.extend_from_slice(&pcr);
212 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
213 assert_eq!(af.program_clock_reference, Some(0));
214 }
215
216 #[test]
217 fn test_pcr_decode_known_value() {
218 let flags = make_flags(false, false, false, true, false, false, false, false);
220 let pcr = encode_pcr(1000, 150);
221 let mut data = vec![flags];
222 data.extend_from_slice(&pcr);
223 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
224 assert_eq!(af.program_clock_reference, Some(300_150));
225 }
226
227 #[test]
228 fn test_pcr_decode_max_base() {
229 let base: u64 = (1 << 33) - 1;
231 let ext: u64 = 299;
232 let flags = make_flags(false, false, false, true, false, false, false, false);
233 let pcr = encode_pcr(base, ext);
234 let mut data = vec![flags];
235 data.extend_from_slice(&pcr);
236 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
237 assert_eq!(af.program_clock_reference, Some(base * 300 + ext));
238 }
239
240 #[test]
241 fn test_pcr_decode_extension_bit8_set() {
242 let base: u64 = 42;
244 let ext: u64 = 256;
245 let flags = make_flags(false, false, false, true, false, false, false, false);
246 let pcr = encode_pcr(base, ext);
247 let mut data = vec![flags];
248 data.extend_from_slice(&pcr);
249 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
250 assert_eq!(af.program_clock_reference, Some(base * 300 + ext));
251 }
252
253 #[test]
254 fn test_opcr_decode() {
255 let base: u64 = 5000;
256 let ext: u64 = 100;
257 let flags = make_flags(false, false, false, false, true, false, false, false);
258 let pcr = encode_pcr(base, ext);
259 let mut data = vec![flags];
260 data.extend_from_slice(&pcr);
261 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
262 assert_eq!(af.original_program_clock_reference, Some(base * 300 + ext));
263 }
264
265 #[test]
266 fn test_pcr_and_opcr_together() {
267 let flags = make_flags(false, false, false, true, true, false, false, false);
268 let pcr = encode_pcr(100, 50);
269 let opcr = encode_pcr(200, 99);
270 let mut data = vec![flags];
271 data.extend_from_slice(&pcr);
272 data.extend_from_slice(&opcr);
273 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
274 assert_eq!(af.program_clock_reference, Some(100 * 300 + 50));
275 assert_eq!(af.original_program_clock_reference, Some(200 * 300 + 99));
276 }
277
278 #[test]
279 fn test_splice_countdown() {
280 let flags = make_flags(false, false, false, false, false, true, false, false);
281 let data = Bytes::from(vec![flags, 42]);
282 let af = AdaptationField::from_bytes(data).unwrap();
283 assert_eq!(af.splice_countdown, Some(42));
284 }
285
286 #[test]
287 fn test_transport_private_data() {
288 let flags = make_flags(false, false, false, false, false, false, true, false);
289 let data = Bytes::from(vec![flags, 3, 0xAA, 0xBB, 0xCC]);
290 let af = AdaptationField::from_bytes(data).unwrap();
291 assert_eq!(
292 af.transport_private_data,
293 Bytes::from_static(&[0xAA, 0xBB, 0xCC])
294 );
295 }
296
297 #[test]
298 fn test_adaptation_field_extension() {
299 let flags = make_flags(false, false, false, false, false, false, false, true);
300 let data = Bytes::from(vec![flags, 2, 0x01, 0x02]);
301 let af = AdaptationField::from_bytes(data).unwrap();
302 assert_eq!(
303 af.adaptation_field_extension,
304 Bytes::from_static(&[0x01, 0x02])
305 );
306 }
307
308 #[test]
309 fn test_all_optional_fields() {
310 let flags = make_flags(true, true, true, true, true, true, true, true);
311 let pcr = encode_pcr(999, 123);
312 let opcr = encode_pcr(888, 77);
313 let splice: u8 = 10;
314 let private = [0xDE, 0xAD];
315 let ext = [0xBE, 0xEF];
316
317 let mut data = vec![flags];
318 data.extend_from_slice(&pcr);
319 data.extend_from_slice(&opcr);
320 data.push(splice);
321 data.push(private.len() as u8);
322 data.extend_from_slice(&private);
323 data.push(ext.len() as u8);
324 data.extend_from_slice(&ext);
325
326 let af = AdaptationField::from_bytes(Bytes::from(data)).unwrap();
327 assert_eq!(af.program_clock_reference, Some(999 * 300 + 123));
328 assert_eq!(af.original_program_clock_reference, Some(888 * 300 + 77));
329 assert_eq!(af.splice_countdown, Some(10));
330 assert_eq!(af.transport_private_data, Bytes::from_static(&[0xDE, 0xAD]));
331 assert_eq!(
332 af.adaptation_field_extension,
333 Bytes::from_static(&[0xBE, 0xEF])
334 );
335 assert!(af.flags.discontinuity_indicator());
336 assert!(af.flags.random_access_indicator());
337 assert!(af.flags.elementary_stream_priority_indicator());
338 }
339
340 #[test]
341 fn test_empty_data_returns_none() {
342 assert!(AdaptationField::from_bytes(Bytes::new()).is_none());
343 }
344
345 #[test]
346 fn test_truncated_pcr_returns_none() {
347 let flags = make_flags(false, false, false, true, false, false, false, false);
348 let data = Bytes::from(vec![flags, 0x00, 0x00, 0x00]);
350 assert!(AdaptationField::from_bytes(data).is_none());
351 }
352
353 #[test]
358 fn test_to_bytes_flags_only() {
359 let af = AdaptationField {
360 adaptation_field_length: 1,
361 flags: AdaptationFieldFlags::new().with_random_access_indicator(true),
362 program_clock_reference: None,
363 original_program_clock_reference: None,
364 splice_countdown: None,
365 transport_private_data: Default::default(),
366 adaptation_field_extension: Default::default(),
367 };
368 let bytes = af.to_bytes();
369 assert_eq!(bytes.len(), 1);
370 assert_eq!(bytes[0], 0b0100_0000); }
372
373 #[test]
374 fn test_to_bytes_pcr_reserved_bits() {
375 let af = AdaptationField {
377 adaptation_field_length: 7,
378 flags: AdaptationFieldFlags::new().with_pcr_flag(true),
379 program_clock_reference: Some(0), original_program_clock_reference: None,
381 splice_countdown: None,
382 transport_private_data: Default::default(),
383 adaptation_field_extension: Default::default(),
384 };
385 let bytes = af.to_bytes();
386 assert_eq!(bytes[5] & 0x7E, 0x7E);
389 }
390
391 #[test]
392 fn test_to_bytes_stuffing() {
393 let af = AdaptationField {
395 adaptation_field_length: 10,
396 flags: AdaptationFieldFlags::new(),
397 program_clock_reference: None,
398 original_program_clock_reference: None,
399 splice_countdown: None,
400 transport_private_data: Default::default(),
401 adaptation_field_extension: Default::default(),
402 };
403 let bytes = af.to_bytes();
404 assert_eq!(bytes.len(), 10);
405 assert!(bytes[1..].iter().all(|&b| b == 0xFF));
406 }
407
408 #[test]
413 fn test_roundtrip_pcr() {
414 for &(base, ext) in &[
415 (0u64, 0u64),
416 (1, 0),
417 (0, 1),
418 (0, 299),
419 (1000, 150),
420 ((1u64 << 33) - 1, 299),
421 (123456789, 42),
422 ] {
423 let pcr_value = base * 300 + ext;
424 let flags = AdaptationFieldFlags::new().with_pcr_flag(true);
425 let af = AdaptationField {
426 adaptation_field_length: 7,
427 flags,
428 program_clock_reference: Some(pcr_value),
429 original_program_clock_reference: None,
430 splice_countdown: None,
431 transport_private_data: Default::default(),
432 adaptation_field_extension: Default::default(),
433 };
434 let bytes = af.to_bytes();
435 let af2 = AdaptationField::from_bytes(Bytes::from(bytes)).unwrap();
436 assert_eq!(
437 af2.program_clock_reference,
438 Some(pcr_value),
439 "roundtrip failed for base={base}, ext={ext}"
440 );
441 }
442 }
443
444 #[test]
445 fn test_roundtrip_all_fields() {
446 let flags = AdaptationFieldFlags::new()
447 .with_discontinuity_indicator(true)
448 .with_pcr_flag(true)
449 .with_opcr_flag(true)
450 .with_splicing_point_flag(true)
451 .with_transport_private_data_flag(true)
452 .with_adaptation_field_extension_flag(true);
453 let af = AdaptationField {
454 adaptation_field_length: 24,
455 flags,
456 program_clock_reference: Some(12345 * 300 + 67),
457 original_program_clock_reference: Some(99999 * 300 + 200),
458 splice_countdown: Some(5),
459 transport_private_data: Bytes::from_static(&[0x01, 0x02, 0x03]),
460 adaptation_field_extension: Bytes::from_static(&[0xAA]),
461 };
462 let bytes = af.to_bytes();
463 let af2 = AdaptationField::from_bytes(Bytes::from(bytes)).unwrap();
464 assert_eq!(af2.program_clock_reference, af.program_clock_reference);
465 assert_eq!(
466 af2.original_program_clock_reference,
467 af.original_program_clock_reference
468 );
469 assert_eq!(af2.splice_countdown, af.splice_countdown);
470 assert_eq!(af2.transport_private_data, af.transport_private_data);
471 assert_eq!(
472 af2.adaptation_field_extension,
473 af.adaptation_field_extension
474 );
475 }
476}