1#![forbid(unsafe_code)]
80#![deny(rust_2018_idioms, future_incompatible)]
81
82pub mod upid;
83
84use bitreader::BitReaderError;
85use log::error;
86use mpeg2ts_reader::demultiplex;
87use mpeg2ts_reader::psi;
88use mpeg2ts_reader::smptera::FormatIdentifier;
89use serde::ser::{SerializeSeq, SerializeStruct};
90use std::convert::TryInto;
91use std::marker;
92
93pub const SCTE35_STREAM_TYPE: mpeg2ts_reader::StreamType = mpeg2ts_reader::StreamType(0x86);
95
96pub fn is_scte35(pmt: &mpeg2ts_reader::psi::pmt::PmtSection<'_>) -> bool {
102 for d in pmt.descriptors().flatten() {
103 if let mpeg2ts_reader::descriptor::CoreDescriptors::Registration(reg) = d {
104 if reg.is_format(FormatIdentifier::CUEI) {
105 return true;
106 }
107 }
108 }
109 false
110}
111#[derive(Debug, PartialEq, serde_derive::Serialize)]
112pub enum EncryptionAlgorithm {
113 None,
114 DesEcb,
115 DesCbc,
116 TripleDesEde3Ecb,
117 Reserved(u8),
118 Private(u8),
119}
120impl EncryptionAlgorithm {
121 pub fn from_id(id: u8) -> EncryptionAlgorithm {
122 match id {
123 0 => EncryptionAlgorithm::None,
124 1 => EncryptionAlgorithm::DesEcb,
125 2 => EncryptionAlgorithm::DesCbc,
126 3 => EncryptionAlgorithm::TripleDesEde3Ecb,
127 _ => {
128 if id < 32 {
129 EncryptionAlgorithm::Reserved(id)
130 } else {
131 EncryptionAlgorithm::Private(id)
132 }
133 }
134 }
135 }
136}
137
138#[derive(Debug, PartialEq, serde_derive::Serialize)]
139pub enum SpliceCommandType {
140 SpliceNull,
141 Reserved(u8),
142 SpliceSchedule,
143 SpliceInsert,
144 TimeSignal,
145 BandwidthReservation,
146 PrivateCommand,
147}
148impl SpliceCommandType {
149 pub fn from_id(id: u8) -> SpliceCommandType {
150 match id {
151 0x00 => SpliceCommandType::SpliceNull,
152 0x04 => SpliceCommandType::SpliceSchedule,
153 0x05 => SpliceCommandType::SpliceInsert,
154 0x06 => SpliceCommandType::TimeSignal,
155 0x07 => SpliceCommandType::BandwidthReservation,
156 0xff => SpliceCommandType::PrivateCommand,
157 _ => SpliceCommandType::Reserved(id),
158 }
159 }
160}
161
162pub struct SpliceInfoHeader<'a> {
167 buf: &'a [u8],
168}
169impl<'a> SpliceInfoHeader<'a> {
170 const HEADER_LENGTH: usize = 11;
171
172 pub fn new(buf: &'a [u8]) -> (SpliceInfoHeader<'a>, &'a [u8]) {
175 if buf.len() < 11 {
176 panic!("buffer too short: {} (expected 11)", buf.len());
177 }
178 let (head, tail) = buf.split_at(11);
179 (SpliceInfoHeader { buf: head }, tail)
180 }
183
184 pub fn protocol_version(&self) -> u8 {
187 self.buf[0]
188 }
189
190 pub fn encrypted_packet(&self) -> bool {
193 self.buf[1] & 0b1000_0000 != 0
194 }
195 pub fn encryption_algorithm(&self) -> EncryptionAlgorithm {
198 EncryptionAlgorithm::from_id((self.buf[1] & 0b0111_1110) >> 1)
199 }
200 pub fn pts_adjustment(&self) -> u64 {
203 u64::from(self.buf[1] & 1) << 32
204 | u64::from(self.buf[2]) << 24
205 | u64::from(self.buf[3]) << 16
206 | u64::from(self.buf[4]) << 8
207 | u64::from(self.buf[5])
208 }
209 pub fn cw_index(&self) -> u8 {
212 self.buf[6]
213 }
214 pub fn tier(&self) -> u16 {
216 u16::from(self.buf[7]) << 4 | u16::from(self.buf[8]) >> 4
217 }
218 pub fn splice_command_length(&self) -> u16 {
220 u16::from(self.buf[8] & 0b0000_1111) << 8 | u16::from(self.buf[9])
221 }
222 pub fn splice_command_type(&self) -> SpliceCommandType {
224 SpliceCommandType::from_id(self.buf[10])
225 }
226}
227impl<'a> serde::Serialize for SpliceInfoHeader<'a> {
228 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
229 where
230 S: serde::Serializer,
231 {
232 let mut s = serializer.serialize_struct("SpliceInfoHeader", 6)?;
233 s.serialize_field("protocol_version", &self.protocol_version())?;
234 s.serialize_field("encrypted_packet", &self.encrypted_packet())?;
235 s.serialize_field("encryption_algorithm", &self.encryption_algorithm())?;
236 s.serialize_field("pts_adjustment", &self.pts_adjustment())?;
237 s.serialize_field("cw_index", &self.cw_index())?;
238 s.serialize_field("tier", &self.tier())?;
239 s.end()
240 }
241}
242impl<'a> std::fmt::Debug for SpliceInfoHeader<'a> {
243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 let mut s = f.debug_struct("SpliceInfoHeader");
245 s.field("protocol_version", &self.protocol_version());
246 s.field("encrypted_packet", &self.encrypted_packet());
247 s.field("encryption_algorithm", &self.encryption_algorithm());
248 s.field("pts_adjustment", &self.pts_adjustment());
249 s.field("cw_index", &self.cw_index());
250 s.field("tier", &self.tier());
251 s.finish()
252 }
253}
254
255#[non_exhaustive]
256#[derive(Debug, serde_derive::Serialize)]
257pub enum SpliceCommand {
258 SpliceNull {},
259 SpliceInsert {
260 splice_event_id: u32,
261 reserved: u8,
262 splice_detail: SpliceInsert,
263 },
264 TimeSignal {
265 splice_time: SpliceTime,
266 },
267 BandwidthReservation {},
268 PrivateCommand {
269 identifier: u32,
270 private_bytes: Vec<u8>,
271 }
272}
273
274#[derive(Debug, serde_derive::Serialize)]
275pub enum NetworkIndicator {
276 Out,
277 In,
278}
279impl NetworkIndicator {
280 pub fn from_flag(id: u8) -> NetworkIndicator {
282 match id {
283 0 => NetworkIndicator::In,
284 1 => NetworkIndicator::Out,
285 _ => panic!(
286 "Invalid out_of_network_indicator value: {} (expected 0 or 1)",
287 id
288 ),
289 }
290 }
291}
292
293#[derive(Debug, serde_derive::Serialize)]
294pub enum SpliceInsert {
295 Cancel,
296 Insert {
297 network_indicator: NetworkIndicator,
298 splice_mode: SpliceMode,
299 duration: Option<SpliceDuration>,
300 unique_program_id: u16,
301 avail_num: u8,
302 avails_expected: u8,
303 },
304}
305
306#[derive(Debug, serde_derive::Serialize)]
307pub enum SpliceTime {
308 Immediate,
309 Timed(Option<u64>),
310}
311
312#[derive(Debug, serde_derive::Serialize)]
313pub struct ComponentSplice {
314 component_tag: u8,
315 splice_time: SpliceTime,
316}
317
318#[derive(Debug, serde_derive::Serialize)]
319pub enum SpliceMode {
320 Program(SpliceTime),
321 Components(Vec<ComponentSplice>),
322}
323
324#[derive(Debug, serde_derive::Serialize)]
325pub enum ReturnMode {
326 Automatic,
327 Manual,
328}
329impl ReturnMode {
330 pub fn from_flag(flag: u8) -> ReturnMode {
331 match flag {
332 0 => ReturnMode::Manual,
333 1 => ReturnMode::Automatic,
334 _ => panic!("Invalid auto_return value: {} (expected 0 or 1)", flag),
335 }
336 }
337}
338
339#[derive(Debug, PartialEq, serde_derive::Serialize, Copy, Clone)]
340pub enum SegmentationUpidType {
341 NotUsed,
342 UserDefinedDeprecated,
343 ISCIDeprecated,
345 AdID,
347 UMID,
348 ISANDeprecated,
349 ISAN,
350 TID,
351 TI,
352 ADI,
353 EIDR,
354 ATSC,
355 MPU,
356 MID,
357 ADS,
358 URI,
359 Reserved(u8),
360}
361impl SegmentationUpidType {
362 pub fn from_type(id: u8) -> SegmentationUpidType {
363 match id {
364 0 => SegmentationUpidType::NotUsed,
365 1 => SegmentationUpidType::UserDefinedDeprecated,
366 2 => SegmentationUpidType::ISCIDeprecated,
367 3 => SegmentationUpidType::AdID,
368 4 => SegmentationUpidType::UMID,
369 5 => SegmentationUpidType::ISANDeprecated,
370 6 => SegmentationUpidType::ISAN,
371 7 => SegmentationUpidType::TID,
372 8 => SegmentationUpidType::TI,
373 9 => SegmentationUpidType::ADI,
374 10 => SegmentationUpidType::EIDR,
375 11 => SegmentationUpidType::ATSC,
376 12 => SegmentationUpidType::MPU,
377 13 => SegmentationUpidType::MID,
378 14 => SegmentationUpidType::ADS,
379 15 => SegmentationUpidType::URI,
380 _ => SegmentationUpidType::Reserved(id),
381 }
382 }
383}
384
385#[derive(Debug, PartialEq, serde_derive::Serialize)]
386pub enum SegmentationTypeId {
387 NotIndicated,
388 ContentIdentification,
389 ProgramStart,
390 ProgramEnd,
391 ProgramEarlyTermination,
392 ProgramBreakaway,
393 ProgramResumption,
394 ProgramRunoverPlanned,
395 ProgramRunoverUnplanned,
396 ProgramOverlapStart,
397 ProgramBlackoutOverride,
398 ProgramStartInProgress,
399 ChapterStart,
400 ChapterEnd,
401 BreakStart,
402 BreakEnd,
403 ProviderAdvertisementStart,
404 ProviderAdvertisementEnd,
405 DistributorAdvertisementStart,
406 DistributorAdvertisementEnd,
407 ProviderPlacementOpportunityStart,
408 ProviderPlacementOpportunityEnd,
409 DistributorPlacementOpportunityStart,
410 DistributorPlacementOpportunityEnd,
411 UnscheduledEventStart,
412 UnscheduledEventEnd,
413 NetworkStart,
414 NetworkEnd,
415 Reserved(u8),
416}
417impl SegmentationTypeId {
418 pub fn from_id(id: u8) -> SegmentationTypeId {
419 match id {
420 0 => SegmentationTypeId::NotIndicated,
421 1 => SegmentationTypeId::ContentIdentification,
422 16 => SegmentationTypeId::ProgramStart,
423 17 => SegmentationTypeId::ProgramEnd,
424 18 => SegmentationTypeId::ProgramEarlyTermination,
425 19 => SegmentationTypeId::ProgramBreakaway,
426 20 => SegmentationTypeId::ProgramResumption,
427 21 => SegmentationTypeId::ProgramRunoverPlanned,
428 22 => SegmentationTypeId::ProgramRunoverUnplanned,
429 23 => SegmentationTypeId::ProgramOverlapStart,
430 24 => SegmentationTypeId::ProgramBlackoutOverride,
431 25 => SegmentationTypeId::ProgramStartInProgress,
432 32 => SegmentationTypeId::ChapterStart,
433 33 => SegmentationTypeId::ChapterEnd,
434 34 => SegmentationTypeId::BreakStart,
435 35 => SegmentationTypeId::BreakEnd,
436 48 => SegmentationTypeId::ProviderAdvertisementStart,
437 49 => SegmentationTypeId::ProviderAdvertisementEnd,
438 50 => SegmentationTypeId::DistributorAdvertisementStart,
439 51 => SegmentationTypeId::DistributorAdvertisementEnd,
440 52 => SegmentationTypeId::ProviderPlacementOpportunityStart,
441 53 => SegmentationTypeId::ProviderPlacementOpportunityEnd,
442 54 => SegmentationTypeId::DistributorPlacementOpportunityStart,
443 55 => SegmentationTypeId::DistributorPlacementOpportunityEnd,
444 64 => SegmentationTypeId::UnscheduledEventStart,
445 65 => SegmentationTypeId::UnscheduledEventEnd,
446 80 => SegmentationTypeId::NetworkStart,
447 81 => SegmentationTypeId::NetworkEnd,
448 _ => SegmentationTypeId::Reserved(id),
449 }
450 }
451}
452
453#[derive(Debug, serde_derive::Serialize)]
454pub enum SegmentationUpid {
455 None,
456 UserDefined(upid::UserDefinedDeprecated),
457 Isci(upid::IsciDeprecated),
458 AdID(upid::AdID),
459 IsanDeprecated(upid::IsanDeprecated),
460 Umid(upid::Umid),
461 TID(upid::TID),
462 TI(upid::TI),
463 ADI(upid::ADI),
464 EIDR(upid::EIDR),
465 ATSC(upid::ATSC),
466 MPU(upid::MPU),
467 MID(Vec<SegmentationUpid>),
468 ADS(upid::ADSInformation),
469 URI(upid::Url),
470 Reserved(SegmentationUpidType, Vec<u8>),
471}
472impl SegmentationUpid {
473 fn parse(
474 r: &mut bitreader::BitReader<'_>,
475 segmentation_upid_type: SegmentationUpidType,
476 segmentation_upid_length: u8,
477 ) -> Result<SegmentationUpid, SpliceDescriptorErr> {
478 if segmentation_upid_length > 0 {
479 let upid_result: Result<Vec<u8>, bitreader::BitReaderError> = (0
480 ..segmentation_upid_length)
481 .map(|_| r.read_u8(8))
482 .collect();
483 let upid = upid_result.named("segmentation_descriptor.segmentation_upid")?;
484 SegmentationUpid::parse_payload(segmentation_upid_type, upid)
485 } else {
486 Ok(SegmentationUpid::None)
487 }
488 }
489
490 fn parse_payload(
492 segmentation_upid_type: SegmentationUpidType,
493 upid: Vec<u8>,
494 ) -> Result<SegmentationUpid, SpliceDescriptorErr> {
495 match segmentation_upid_type {
496 SegmentationUpidType::NotUsed => Err(
497 SpliceDescriptorErr::SegmentationUpidLengthTypeMismatch(segmentation_upid_type),
498 ),
499 SegmentationUpidType::UserDefinedDeprecated => Self::parse_user_defined(upid),
500 SegmentationUpidType::ISCIDeprecated => Self::parse_isci(upid),
501 SegmentationUpidType::AdID => Self::parse_adid(upid),
502 SegmentationUpidType::UMID => Self::parse_umid(upid),
503 SegmentationUpidType::ISANDeprecated => Self::parse_isan_deprecated(upid),
504 SegmentationUpidType::ISAN => Self::parse_isan(upid),
505 SegmentationUpidType::TID => Self::parse_tid(upid),
506 SegmentationUpidType::TI => Self::parse_ti(upid),
507 SegmentationUpidType::ADI => Self::parse_adi(upid),
508 SegmentationUpidType::EIDR => Self::parse_eidr(upid),
509 SegmentationUpidType::ATSC => Self::parse_atsc(upid),
510 SegmentationUpidType::MPU => Self::parse_mpu(upid),
511 SegmentationUpidType::MID => Self::parse_mid(upid),
512 SegmentationUpidType::ADS => Self::parse_ads(upid),
513 SegmentationUpidType::URI => Self::parse_url(upid),
514 SegmentationUpidType::Reserved(_) => Self::parse_reserved(segmentation_upid_type, upid),
515 }
516 }
517
518 pub fn segmentation_upid_length(&self) -> usize {
519 match self {
520 SegmentationUpid::None => 0,
521 SegmentationUpid::UserDefined(v) => v.0.len(),
522 SegmentationUpid::Isci(_) => 8,
523 SegmentationUpid::AdID(_) => 12,
524 SegmentationUpid::IsanDeprecated(_) => 8,
525 SegmentationUpid::Umid(_) => 32,
526 SegmentationUpid::TID(_) => 12,
527 SegmentationUpid::TI(_) => 8,
528 SegmentationUpid::ADI(adi) => adi.0.len(),
529 SegmentationUpid::EIDR(_) => 12,
530 SegmentationUpid::ATSC(atsc) => atsc.0.len(),
531 SegmentationUpid::MPU(m) => m.0.len(),
532 SegmentationUpid::MID(v) => {
533 v.len() * 2
534 + v.iter()
535 .map(|upid| upid.segmentation_upid_length())
536 .sum::<usize>()
537 }
538 SegmentationUpid::ADS(a) => a.0.len(),
539 SegmentationUpid::URI(u) => u.0.as_str().len(),
540 SegmentationUpid::Reserved(_, r) => r.len(),
541 }
542 }
543
544 pub fn segmentation_upid_type(&self) -> SegmentationUpidType {
545 match self {
546 SegmentationUpid::None => SegmentationUpidType::NotUsed,
547 SegmentationUpid::UserDefined(_) => SegmentationUpidType::UserDefinedDeprecated,
548 SegmentationUpid::Isci(_) => SegmentationUpidType::ISCIDeprecated,
549 SegmentationUpid::AdID(_) => SegmentationUpidType::AdID,
550 SegmentationUpid::IsanDeprecated(_) => SegmentationUpidType::ISAN,
551 SegmentationUpid::Umid(_) => SegmentationUpidType::UMID,
552 SegmentationUpid::TID(_) => SegmentationUpidType::TID,
553 SegmentationUpid::TI(_) => SegmentationUpidType::TI,
554 SegmentationUpid::ADI(_) => SegmentationUpidType::ADI,
555 SegmentationUpid::EIDR(_) => SegmentationUpidType::EIDR,
556 SegmentationUpid::ATSC(_) => SegmentationUpidType::ATSC,
557 SegmentationUpid::MPU(_) => SegmentationUpidType::MPU,
558 SegmentationUpid::MID(_) => SegmentationUpidType::MID,
559 SegmentationUpid::ADS(_) => SegmentationUpidType::ADS,
560 SegmentationUpid::URI(_) => SegmentationUpidType::URI,
561 SegmentationUpid::Reserved(t, _) => *t,
562 }
563 }
564
565 fn parse_user_defined(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
566 Ok(SegmentationUpid::UserDefined(upid::UserDefinedDeprecated(
567 upid,
568 )))
569 }
570 fn parse_isci(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
571 chk_upid(&upid, 8, SegmentationUpidType::ISCIDeprecated)?;
572 upid_from_utf8(upid, SegmentationUpidType::ISCIDeprecated)
573 .map(|s| SegmentationUpid::Isci(upid::IsciDeprecated(s)))
574 }
575 fn parse_adid(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
576 chk_upid(&upid, 12, SegmentationUpidType::AdID)?;
577 upid_from_utf8(upid, SegmentationUpidType::AdID)
578 .map(|s| SegmentationUpid::AdID(upid::AdID(s)))
579 }
580 fn parse_umid(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
581 chk_upid(&upid, 32, SegmentationUpidType::UMID)?;
582 Ok(SegmentationUpid::Umid(upid::Umid(upid)))
583 }
584 fn parse_isan_deprecated(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
585 chk_upid(&upid, 8, SegmentationUpidType::ISANDeprecated)?;
586 Ok(SegmentationUpid::IsanDeprecated(upid::IsanDeprecated(upid)))
587 }
588 fn parse_isan(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
589 chk_upid(&upid, 12, SegmentationUpidType::ISAN)?;
590 Ok(SegmentationUpid::IsanDeprecated(upid::IsanDeprecated(upid)))
591 }
592 fn parse_tid(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
593 chk_upid(&upid, 12, SegmentationUpidType::TID)?;
594 upid_from_utf8(upid, SegmentationUpidType::TID).map(|s| SegmentationUpid::TID(upid::TID(s)))
595 }
596 fn parse_ti(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
597 chk_upid(&upid, 8, SegmentationUpidType::TI)?;
598 Ok(SegmentationUpid::TI(upid::TI(upid)))
599 }
600 fn parse_adi(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
601 upid_from_utf8(upid, SegmentationUpidType::ADI).map(|s| SegmentationUpid::ADI(upid::ADI(s)))
602 }
603 fn parse_eidr(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
604 chk_upid(&upid, 12, SegmentationUpidType::EIDR)?;
605 Ok(SegmentationUpid::EIDR(upid::EIDR(
606 upid.as_slice().try_into().unwrap(),
607 )))
608 }
609 fn parse_atsc(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
610 Ok(SegmentationUpid::ATSC(upid::ATSC(upid)))
611 }
612 fn parse_mpu(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
613 Ok(SegmentationUpid::MPU(upid::MPU(upid)))
614 }
615 fn parse_mid(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
616 let mut data = &upid[..];
617 let mut result = vec![];
618 while !data.is_empty() {
619 if data.len() < 2 {
620 return Err(SpliceDescriptorErr::not_enough_data("MID.length", 1, 0));
621 }
622 let segmentation_upid_type = SegmentationUpidType::from_type(data[0]);
623 let length = data[1] as usize;
624 let payload_end = 2 + length;
625 if data.len() < payload_end {
626 return Err(SpliceDescriptorErr::not_enough_data(
627 "MID.segmentation_upid",
628 length,
629 data.len() - 2,
630 ));
631 }
632 let payload = &data[2..payload_end];
633 result.push(Self::parse_payload(
634 segmentation_upid_type,
635 payload.to_vec(),
636 )?);
637 data = &data[payload_end..];
638 }
639 Ok(SegmentationUpid::MID(result))
640 }
641 fn parse_ads(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
642 Ok(SegmentationUpid::ADS(upid::ADSInformation(upid)))
643 }
644 fn parse_url(upid: Vec<u8>) -> Result<SegmentationUpid, SpliceDescriptorErr> {
645 upid_from_utf8(upid, SegmentationUpidType::URI)
646 .and_then(|s| {
647 url::Url::parse(&s).map_err(|_| SpliceDescriptorErr::InvalidUpidContent {
648 upid_type: SegmentationUpidType::URI,
649 bytes: s.into_bytes(),
650 })
651 })
652 .map(|u| SegmentationUpid::URI(upid::Url(u)))
653 }
654 fn parse_reserved(
655 segmentation_upid_type: SegmentationUpidType,
656 upid: Vec<u8>,
657 ) -> Result<SegmentationUpid, SpliceDescriptorErr> {
658 Ok(SegmentationUpid::Reserved(segmentation_upid_type, upid))
659 }
660}
661
662fn upid_from_utf8(
664 upid: Vec<u8>,
665 upid_type: SegmentationUpidType,
666) -> Result<String, SpliceDescriptorErr> {
667 String::from_utf8(upid).map_err(|e| SpliceDescriptorErr::InvalidUpidContent {
668 upid_type,
669 bytes: e.into_bytes(),
670 })
671}
672
673fn chk_upid(
674 upid: &[u8],
675 expected: usize,
676 upid_type: SegmentationUpidType,
677) -> Result<(), SpliceDescriptorErr> {
678 if upid.len() == expected {
679 Ok(())
680 } else {
681 Err(SpliceDescriptorErr::InvalidUpidLength {
682 upid_type,
683 expected,
684 actual: upid.len(),
685 })
686 }
687}
688
689#[derive(Debug, serde_derive::Serialize)]
690pub enum DeviceRestrictions {
691 RestrictGroup0,
692 RestrictGroup1,
693 RestrictGroup2,
694 None,
695}
696impl DeviceRestrictions {
697 pub fn from_bits(restriction: u8) -> DeviceRestrictions {
699 match restriction {
700 0 => DeviceRestrictions::RestrictGroup0,
701 1 => DeviceRestrictions::RestrictGroup1,
702 2 => DeviceRestrictions::RestrictGroup2,
703 3 => DeviceRestrictions::None,
704 _ => panic!(
705 "Invalid device_restrictions value: {} (expected 0, 1, 2, 3)",
706 restriction
707 ),
708 }
709 }
710}
711
712#[derive(Debug, serde_derive::Serialize)]
713pub enum DeliveryRestrictionFlags {
714 None,
715 DeliveryRestrictions {
716 web_delivery_allowed_flag: bool,
717 no_regional_blackout_flag: bool,
718 archive_allowed_flag: bool,
719 device_restrictions: DeviceRestrictions,
720 },
721}
722
723#[derive(Debug, serde_derive::Serialize)]
724pub enum SegmentationMode {
725 Program,
726 Component {
727 components: Vec<SegmentationModeComponent>,
728 },
729}
730
731#[derive(Debug, serde_derive::Serialize)]
732pub struct SegmentationModeComponent {
733 component_tag: u8,
734 pts_offset: u64,
735}
736
737#[derive(Debug, serde_derive::Serialize)]
738pub enum SegmentationDescriptor {
739 Cancel,
740 Insert {
741 program_segmentation_flag: bool,
742 segmentation_duration_flag: bool,
743 delivery_not_restricted_flag: bool,
744 delivery_restrictions: DeliveryRestrictionFlags,
745 segmentation_mode: SegmentationMode,
746 segmentation_duration: Option<u64>,
747 segmentation_upid: SegmentationUpid,
748 segmentation_type_id: SegmentationTypeId,
749 segment_num: u8,
750 segments_expected: u8,
751 sub_segments: Option<SubSegments>,
752 },
753}
754
755#[derive(Debug, serde_derive::Serialize)]
756pub struct SubSegments {
757 sub_segment_num: u8,
758 sub_segments_expected: u8,
759}
760
761#[derive(Debug, serde_derive::Serialize)]
762pub struct SpliceDuration {
763 return_mode: ReturnMode,
764 duration: u64,
765}
766
767pub trait SpliceInfoProcessor {
768 fn process(
769 &self,
770 header: SpliceInfoHeader<'_>,
771 command: SpliceCommand,
772 descriptors: SpliceDescriptors<'_>,
773 );
774}
775
776#[derive(Debug, serde_derive::Serialize)]
777pub enum SpliceDescriptor {
778 AvailDescriptor {
779 provider_avail_id: u32,
780 },
781 DTMFDescriptor {
782 preroll: u8,
783 dtmf_chars: Vec<u8>,
784 },
785 SegmentationDescriptor {
786 segmentation_event_id: u32,
787 descriptor_detail: SegmentationDescriptor,
788 },
789 TimeDescriptor {
790 tai_seconds: u64,
791 tai_nanoseconds: u32,
792 utc_offset: u16,
793 },
794 Reserved {
795 tag: u8,
796 identifier: [u8; 4],
797 private_bytes: Vec<u8>,
798 },
799}
800impl SpliceDescriptor {
801 fn parse_segmentation_descriptor_details(
802 r: &mut bitreader::BitReader<'_>,
803 cancelled: bool,
804 ) -> Result<SegmentationDescriptor, SpliceDescriptorErr> {
805 if cancelled {
806 Ok(SegmentationDescriptor::Cancel)
807 } else {
808 let program_segmentation_flag = r
809 .read_bool()
810 .named("segmentation_descriptor.program_segmentation_flag")?;
811 let segmentation_duration_flag = r
812 .read_bool()
813 .named("segmentation_descriptor.segmentation_duration_flag")?;
814 let delivery_not_restricted_flag = r
815 .read_bool()
816 .named("segmentation_descriptor.delivery_not_restricted_flag")?;
817 let delivery_restrictions;
818 if !delivery_not_restricted_flag {
819 delivery_restrictions = DeliveryRestrictionFlags::DeliveryRestrictions {
820 web_delivery_allowed_flag: r
821 .read_bool()
822 .named("segmentation_descriptor.web_delivery_allowed_flag")?,
823 no_regional_blackout_flag: r
824 .read_bool()
825 .named("segmentation_descriptor.no_regional_blackout_flag")?,
826 archive_allowed_flag: r
827 .read_bool()
828 .named("segmentation_descriptor.archive_allowed_flag")?,
829 device_restrictions: DeviceRestrictions::from_bits(
830 r.read_u8(2)
831 .named("segmentation_descriptor.device_restrictions")?,
832 ),
833 }
834 } else {
835 delivery_restrictions = DeliveryRestrictionFlags::None;
836 r.skip(5).named("segmentation_descriptor.reserved")?;
837 }
838 let segmentation_mode = if !program_segmentation_flag {
839 let component_count = r
840 .read_u8(8)
841 .named("segmentation_descriptor.component_count")?;
842 let mut components = Vec::with_capacity(component_count as usize);
843
844 for _ in 0..component_count {
845 let component_tag = r
846 .read_u8(8)
847 .named("segmentation_descriptor.component.component_tag")?;
848 r.skip(7)
849 .named("segmentation_descriptor.component.reserved")?;
850 let pts_offset = r
851 .read_u64(33)
852 .named("segmentation_descriptor.component.pts_offset")?;
853 components.push(SegmentationModeComponent {
854 component_tag,
855 pts_offset,
856 })
857 }
858
859 SegmentationMode::Component { components }
860 } else {
861 SegmentationMode::Program
862 };
863
864 let segmentation_duration = if segmentation_duration_flag {
865 Some(
866 r.read_u64(40)
867 .named("segmentation_descriptor.segmentation_duration")?,
868 )
869 } else {
870 None
871 };
872
873 let segmentation_upid_type = SegmentationUpidType::from_type(
874 r.read_u8(8)
875 .named("segmentation_descriptor.segmentation_upid_type")?,
876 );
877 let segmentation_upid_length = r
878 .read_u8(8)
879 .named("segmentation_descriptor.segmentation_upid_length")?;
880 let segmentation_upid =
881 SegmentationUpid::parse(r, segmentation_upid_type, segmentation_upid_length)?;
882
883 let segmentation_type_id =
884 SegmentationTypeId::from_id(r.read_u8(8).named("segmentation_type_id")?);
885 let segment_num = r.read_u8(8).named("segment_num")?;
886 let segments_expected = r.read_u8(8).named("segments_expected")?;
887
888 let sub_segments = if r.relative_reader().skip(1).is_ok() {
892 Some(SubSegments {
893 sub_segment_num: r.read_u8(8).named("sub_segment_num")?,
894 sub_segments_expected: r.read_u8(8).named("sub_segments_expected")?,
895 })
896 } else {
897 None
898 };
899
900 Ok(SegmentationDescriptor::Insert {
901 program_segmentation_flag,
902 segmentation_duration_flag,
903 delivery_not_restricted_flag,
904 delivery_restrictions,
905 segmentation_mode,
906 segmentation_duration,
907 segmentation_upid,
908 segmentation_type_id,
909 segment_num,
910 segments_expected,
911 sub_segments,
912 })
913 }
914 }
915
916 fn parse_segmentation_descriptor(buf: &[u8]) -> Result<SpliceDescriptor, SpliceDescriptorErr> {
917 let mut r = bitreader::BitReader::new(buf);
918 let id = r.read_u32(32).named("segmentation_descriptor.id")?;
919 let cancel = r.read_bool().named("segmentation_descriptor.cancel")?;
920 r.skip(7).named("segmentation_descriptor.reserved")?;
921
922 let result = SpliceDescriptor::SegmentationDescriptor {
923 segmentation_event_id: id,
924 descriptor_detail: Self::parse_segmentation_descriptor_details(&mut r, cancel)?,
925 };
926
927 assert!(r.is_aligned(1));
930
931 if buf.len() > (r.position() / 8) as usize {
932 error!(
933 "only {} bytes consumed data in segmentation_descriptor of {} bytes",
934 r.position() / 8,
935 buf.len()
936 );
937 }
938 Ok(result)
939 }
940
941 fn parse_dtmf_descriptor(buf: &[u8]) -> Result<SpliceDescriptor, SpliceDescriptorErr> {
942 let mut r = bitreader::BitReader::new(buf);
943 let preroll = r.read_u8(8).named("dtmf_descriptor.preroll")?;
944 let dtmf_count = r.read_u8(3).named("dtmf_descriptor.dtmf_count")?;
945 r.skip(5).named("dtmf_descriptor.reserved")?;
946 let dtmf_chars_result: Result<Vec<u8>, BitReaderError> =
947 (0..dtmf_count).map(|_| r.read_u8(8)).collect();
948 let dtmf_chars = dtmf_chars_result.named("dtmf_descriptor")?;
949
950 assert!(r.is_aligned(1));
953
954 if buf.len() > (r.position() / 8) as usize {
955 error!(
956 "only {} bytes consumed data in segmentation_descriptor of {} bytes",
957 r.position() / 8,
958 buf.len()
959 );
960 }
961
962 Ok(SpliceDescriptor::DTMFDescriptor {
963 preroll,
964 dtmf_chars,
965 })
966 }
967 fn parse(buf: &[u8]) -> Result<SpliceDescriptor, SpliceDescriptorErr> {
968 if buf.len() < 6 {
969 return Err(SpliceDescriptorErr::NotEnoughData {
970 field_name: "splice_descriptor",
971 actual: buf.len(),
972 expected: 6,
973 });
974 }
975 let splice_descriptor_tag = buf[0];
976 let splice_descriptor_len = buf[1] as usize;
977 if splice_descriptor_len < 4 {
978 return Err(SpliceDescriptorErr::InvalidDescriptorLength(
980 splice_descriptor_len,
981 ));
982 }
983 let splice_descriptor_end = splice_descriptor_len + 2;
984 if splice_descriptor_end > buf.len() {
985 return Err(SpliceDescriptorErr::NotEnoughData {
986 field_name: "splice_descriptor.private_byte",
987 actual: buf.len(),
988 expected: splice_descriptor_end,
989 });
990 }
991 let id = &buf[2..6];
992 let payload = &buf[6..splice_descriptor_end];
993 if id == b"CUEI" {
994 match splice_descriptor_tag {
995 0x00 => Self::parse_avail_descriptor(payload),
996 0x01 => Self::parse_dtmf_descriptor(payload),
997 0x02 => Self::parse_segmentation_descriptor(payload),
998 0x03 => Self::parse_time_descriptor(payload),
999 _ => Self::parse_reserved(payload, splice_descriptor_tag, id),
1000 }
1001 } else {
1002 Self::parse_reserved(payload, splice_descriptor_tag, id)
1003 }
1004 }
1005
1006 fn parse_reserved(
1007 buf: &[u8],
1008 splice_descriptor_tag: u8,
1009 id: &[u8],
1010 ) -> Result<SpliceDescriptor, SpliceDescriptorErr> {
1011 Ok(SpliceDescriptor::Reserved {
1012 tag: splice_descriptor_tag,
1013 identifier: [id[0], id[1], id[2], id[3]],
1014 private_bytes: buf.to_owned(),
1015 })
1016 }
1017
1018 fn parse_avail_descriptor(buf: &[u8]) -> Result<SpliceDescriptor, SpliceDescriptorErr> {
1019 if buf.len() < 4 {
1020 return Err(SpliceDescriptorErr::NotEnoughData {
1021 field_name: "avail_descriptor",
1022 expected: 4,
1023 actual: buf.len(),
1024 });
1025 }
1026 Ok(SpliceDescriptor::AvailDescriptor {
1027 provider_avail_id: u32::from(buf[0]) << 24
1028 | u32::from(buf[1]) << 16
1029 | u32::from(buf[2]) << 8
1030 | u32::from(buf[3]),
1031 })
1032 }
1033
1034 fn parse_time_descriptor(buf: &[u8]) -> Result<SpliceDescriptor, SpliceDescriptorErr> {
1035 if buf.len() < 12 {
1036 return Err(SpliceDescriptorErr::NotEnoughData {
1037 field_name: "time_descriptor",
1038 expected: 12,
1039 actual: buf.len(),
1040 });
1041 }
1042 Ok(SpliceDescriptor::TimeDescriptor {
1043 tai_seconds: u64::from(buf[0]) << 40
1044 | u64::from(buf[1]) << 32
1045 | u64::from(buf[2]) << 24
1046 | u64::from(buf[3]) << 16
1047 | u64::from(buf[4]) << 8
1048 | u64::from(buf[5]),
1049 tai_nanoseconds: u32::from(buf[6]) << 24
1050 | u32::from(buf[7]) << 16
1051 | u32::from(buf[8]) << 8
1052 | u32::from(buf[9]),
1053 utc_offset: u16::from(buf[10]) << 8 | u16::from(buf[11]),
1054 })
1055 }
1056}
1057
1058#[derive(Debug, serde_derive::Serialize)]
1059pub enum SpliceDescriptorErr {
1060 InvalidDescriptorLength(usize),
1061 NotEnoughData {
1062 field_name: &'static str,
1063 expected: usize,
1064 actual: usize,
1065 },
1066 SegmentationUpidLengthTypeMismatch(SegmentationUpidType),
1069 InvalidUpidContent {
1071 upid_type: SegmentationUpidType,
1072 bytes: Vec<u8>,
1073 },
1074 InvalidUpidLength {
1076 upid_type: SegmentationUpidType,
1077 expected: usize,
1078 actual: usize,
1079 },
1080}
1081impl SpliceDescriptorErr {
1082 fn not_enough_data(
1083 field_name: &'static str,
1084 expected: usize,
1085 actual: usize,
1086 ) -> SpliceDescriptorErr {
1087 SpliceDescriptorErr::NotEnoughData {
1088 field_name,
1089 expected,
1090 actual,
1091 }
1092 }
1093}
1094
1095trait ErrorFieldNamed<T> {
1096 fn named(self, field_name: &'static str) -> Result<T, SpliceDescriptorErr>;
1097}
1098impl<T> ErrorFieldNamed<T> for Result<T, bitreader::BitReaderError> {
1099 fn named(self, field_name: &'static str) -> Result<T, SpliceDescriptorErr> {
1100 match self {
1101 Err(bitreader::BitReaderError::NotEnoughData {
1102 position,
1103 length,
1104 requested,
1105 }) => {
1106 Err(SpliceDescriptorErr::NotEnoughData {
1108 field_name,
1109 expected: (requested / 8) as usize,
1110 actual: ((length - position) / 8) as usize,
1111 })
1112 }
1113 Err(e) => {
1114 panic!("scte35-reader bug: {:?}", e)
1115 }
1116 Ok(v) => Ok(v),
1117 }
1118 }
1119}
1120
1121pub struct SpliceDescriptors<'buf> {
1122 buf: &'buf [u8],
1123}
1124impl<'buf> IntoIterator for &SpliceDescriptors<'buf> {
1125 type Item = Result<SpliceDescriptor, SpliceDescriptorErr>;
1126 type IntoIter = SpliceDescriptorIter<'buf>;
1127
1128 fn into_iter(self) -> <Self as IntoIterator>::IntoIter {
1129 SpliceDescriptorIter::new(self.buf)
1130 }
1131}
1132impl<'a> serde::Serialize for SpliceDescriptors<'a> {
1133 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1134 where
1135 S: serde::Serializer,
1136 {
1137 let mut s = serializer.serialize_seq(None)?;
1138 for elem in self.into_iter().flatten() {
1139 s.serialize_element(&elem)?;
1140 }
1141 s.end()
1142 }
1143}
1144
1145pub struct SpliceDescriptorIter<'buf> {
1146 buf: &'buf [u8],
1147}
1148impl<'buf> SpliceDescriptorIter<'buf> {
1149 fn new(buf: &'buf [u8]) -> SpliceDescriptorIter<'buf> {
1150 SpliceDescriptorIter { buf }
1151 }
1152}
1153impl<'buf> Iterator for SpliceDescriptorIter<'buf> {
1154 type Item = Result<SpliceDescriptor, SpliceDescriptorErr>;
1155
1156 fn next(&mut self) -> Option<Self::Item> {
1157 if self.buf.is_empty() {
1158 return None;
1159 }
1160 if self.buf.len() < 6 {
1161 self.buf = &self.buf[0..0];
1162 return Some(Err(SpliceDescriptorErr::NotEnoughData {
1163 field_name: "splice_descriptor",
1164 expected: 2,
1165 actual: self.buf.len(),
1166 }));
1167 }
1168 let descriptor_length = self.buf[1] as usize;
1169 if self.buf.len() < descriptor_length + 2 {
1170 self.buf = &self.buf[0..0];
1171 return Some(Err(SpliceDescriptorErr::NotEnoughData {
1172 field_name: "splice_descriptor",
1173 expected: descriptor_length + 2,
1174 actual: self.buf.len(),
1175 }));
1176 }
1177 if descriptor_length > 254 {
1178 self.buf = &self.buf[0..0];
1179 return Some(Err(SpliceDescriptorErr::InvalidDescriptorLength(
1180 descriptor_length,
1181 )));
1182 }
1183 let (desc, rest) = self.buf.split_at(2 + descriptor_length);
1184 let result = SpliceDescriptor::parse(desc);
1185 self.buf = rest;
1186 Some(result)
1187 }
1188}
1189
1190pub struct Scte35SectionProcessor<P, Ctx: demultiplex::DemuxContext>
1191where
1192 P: SpliceInfoProcessor,
1193{
1194 processor: P,
1195 phantom: marker::PhantomData<Ctx>,
1196}
1197impl<P, Ctx: demultiplex::DemuxContext> psi::WholeCompactSyntaxPayloadParser
1198 for Scte35SectionProcessor<P, Ctx>
1199where
1200 P: SpliceInfoProcessor,
1201{
1202 type Context = Ctx;
1203
1204 fn section(
1205 &mut self,
1206 _ctx: &mut Self::Context,
1207 header: &psi::SectionCommonHeader,
1208 data: &[u8],
1209 ) {
1210 if header.table_id == 0xfc {
1211 if !cfg!(fuzzing) {
1213 let crc = mpeg2ts_reader::mpegts_crc::sum32(data);
1214 if crc != 0 {
1215 error!("section CRC check failed {:#08x}", crc);
1216 return;
1217 }
1218 }
1219 let section_data = &data[psi::SectionCommonHeader::SIZE..];
1220 if section_data.len() < SpliceInfoHeader::HEADER_LENGTH + 4 {
1221 error!(
1222 "section data too short: {} (must be at least {})",
1223 section_data.len(),
1224 SpliceInfoHeader::HEADER_LENGTH + 4
1225 );
1226 return;
1227 }
1228 let section_data = §ion_data[..section_data.len() - 4];
1230 let (splice_header, rest) = SpliceInfoHeader::new(section_data);
1231 if splice_header.encrypted_packet() {
1232 error!("encrypted SCTE-35 data not supoprted");
1233 return;
1234 }
1235 let command_len = splice_header.splice_command_length() as usize;
1236 if command_len > rest.len() {
1237 error!("splice_command_length of {} bytes is too long to fit in remaining {} bytes of section data", command_len, rest.len());
1238 return;
1239 }
1240 let (payload, rest) = rest.split_at(command_len);
1241 if rest.len() < 2 {
1242 error!("end of section data while trying to read descriptor_loop_length");
1243 return;
1244 }
1245 let descriptor_loop_length = (u16::from(rest[0]) << 8 | u16::from(rest[1])) as usize;
1246 if descriptor_loop_length + 2 > rest.len() {
1247 error!("descriptor_loop_length of {} bytes is too long to fit in remaining {} bytes of section data", descriptor_loop_length, rest.len());
1248 return;
1249 }
1250 let descriptors = &rest[2..2 + descriptor_loop_length];
1251 let splice_command = match splice_header.splice_command_type() {
1252 SpliceCommandType::SpliceNull => Some(Self::splice_null(payload)),
1253 SpliceCommandType::SpliceInsert => Some(Self::splice_insert(payload)),
1254 SpliceCommandType::TimeSignal => Some(Self::time_signal(payload)),
1255 SpliceCommandType::BandwidthReservation => {
1256 Some(Self::bandwidth_reservation(payload))
1257 }
1258 SpliceCommandType::PrivateCommand => Some(Self::private_command(payload)),
1259 _ => None,
1260 };
1261 match splice_command {
1262 Some(Ok(splice_command)) => {
1263 self.processor.process(
1264 splice_header,
1265 splice_command,
1266 SpliceDescriptors { buf: descriptors },
1267 );
1268 }
1269 Some(Err(e)) => {
1270 error!("parse error: {:?}", e);
1271 }
1272 None => {
1273 error!(
1274 "unhandled command {:?}",
1275 splice_header.splice_command_type()
1276 );
1277 }
1278 }
1279 } else {
1280 error!(
1281 "bad table_id for scte35: {:#x} (expected 0xfc)",
1282 header.table_id
1283 );
1284 }
1285 }
1286}
1287impl<P, Ctx: demultiplex::DemuxContext> Scte35SectionProcessor<P, Ctx>
1288where
1289 P: SpliceInfoProcessor,
1290{
1291 pub fn new(processor: P) -> Scte35SectionProcessor<P, Ctx> {
1292 Scte35SectionProcessor {
1293 processor,
1294 phantom: marker::PhantomData,
1295 }
1296 }
1297 fn splice_null(payload: &[u8]) -> Result<SpliceCommand, SpliceDescriptorErr> {
1298 if payload.is_empty() {
1299 Ok(SpliceCommand::SpliceNull {})
1300 } else {
1301 Err(SpliceDescriptorErr::InvalidDescriptorLength(payload.len()))
1302 }
1303 }
1304
1305 fn splice_insert(payload: &[u8]) -> Result<SpliceCommand, SpliceDescriptorErr> {
1306 let mut r = bitreader::BitReader::new(payload);
1307
1308 let splice_event_id = r.read_u32(32).named("splice_insert.splice_event_id")?;
1309 let splice_event_cancel_indicator = r
1310 .read_bool()
1311 .named("splice_insert.splice_event_cancel_indicator")?;
1312 let reserved = r.read_u8(7).named("splice_insert.reserved")?;
1313 let result = SpliceCommand::SpliceInsert {
1314 splice_event_id,
1315 reserved,
1316 splice_detail: Self::read_splice_detail(&mut r, splice_event_cancel_indicator)?,
1317 };
1318
1319 assert!(r.is_aligned(1));
1322
1323 if payload.len() > (r.position() / 8) as usize {
1324 error!(
1325 "only {} bytes consumed data in splice_insert of {} bytes",
1326 r.position() / 8,
1327 payload.len()
1328 );
1329 }
1330 Ok(result)
1331 }
1332
1333 fn time_signal(payload: &[u8]) -> Result<SpliceCommand, SpliceDescriptorErr> {
1334 let mut r = bitreader::BitReader::new(payload);
1335
1336 let result = SpliceCommand::TimeSignal {
1337 splice_time: SpliceTime::Timed(Self::read_splice_time(&mut r)?),
1338 };
1339
1340 assert!(r.is_aligned(1));
1343
1344 if payload.len() > (r.position() / 8) as usize {
1345 error!(
1346 "only {} bytes consumed data in time_signal of {} bytes",
1347 r.position() / 8,
1348 payload.len()
1349 );
1350 }
1351 Ok(result)
1352 }
1353
1354 fn bandwidth_reservation(payload: &[u8]) -> Result<SpliceCommand, SpliceDescriptorErr> {
1355 if payload.is_empty() {
1356 Ok(SpliceCommand::BandwidthReservation {})
1357 } else {
1358 Err(SpliceDescriptorErr::InvalidDescriptorLength(payload.len()))
1359 }
1360 }
1361
1362 fn private_command(payload: &[u8]) -> Result<SpliceCommand, SpliceDescriptorErr> {
1363 let mut r = bitreader::BitReader::new(payload);
1364 let identifier = r.read_u32(32).named("private_command.identifier")?;
1365 Ok(SpliceCommand::PrivateCommand {
1366 identifier,
1367 private_bytes: payload[4..].to_vec(),
1368 })
1369 }
1370
1371 fn read_splice_detail(
1372 r: &mut bitreader::BitReader<'_>,
1373 splice_event_cancel_indicator: bool,
1374 ) -> Result<SpliceInsert, SpliceDescriptorErr> {
1375 if splice_event_cancel_indicator {
1376 Ok(SpliceInsert::Cancel)
1377 } else {
1378 r.relative_reader().skip(1).named("splice_insert.flags")?;
1379 let network_indicator =
1380 NetworkIndicator::from_flag(r.read_u8(1).named("splice_insert.network_indicator")?);
1381 let program_splice_flag = r.read_bool().named("splice_insert.program_splice_flag")?;
1382 let duration_flag = r.read_bool().named("splice_insert.duration_flag")?;
1383 let splice_immediate_flag =
1384 r.read_bool().named("splice_insert.splice_immediate_flag")?;
1385 r.skip(4).named("splice_insert.reserved")?;
1386
1387 Ok(SpliceInsert::Insert {
1388 network_indicator,
1389 splice_mode: Self::read_splice_mode(r, program_splice_flag, splice_immediate_flag)?,
1390 duration: if duration_flag {
1391 Some(Self::read_duration(r)?)
1392 } else {
1393 None
1394 },
1395 unique_program_id: r.read_u16(16).named("unique_program_id")?,
1396 avail_num: r.read_u8(8).named("avail_num")?,
1397 avails_expected: r.read_u8(8).named("avails_expected")?,
1398 })
1399 }
1400 }
1401
1402 fn read_splice_mode(
1403 r: &mut bitreader::BitReader<'_>,
1404 program_splice_flag: bool,
1405 splice_immediate_flag: bool,
1406 ) -> Result<SpliceMode, SpliceDescriptorErr> {
1407 if program_splice_flag {
1408 let time = if splice_immediate_flag {
1409 SpliceTime::Immediate
1410 } else {
1411 SpliceTime::Timed(Self::read_splice_time(r)?)
1412 };
1413 Ok(SpliceMode::Program(time))
1414 } else {
1415 let component_count = r.read_u8(8).named("component_count")? as usize;
1416 let mut components = Vec::with_capacity(component_count);
1417 for _ in 0..component_count {
1418 let component_tag = r.read_u8(8).named("component_tag")?;
1419 let splice_time = if splice_immediate_flag {
1420 SpliceTime::Immediate
1421 } else {
1422 SpliceTime::Timed(Self::read_splice_time(r)?)
1423 };
1424 components.push(ComponentSplice {
1425 component_tag,
1426 splice_time,
1427 });
1428 }
1429 Ok(SpliceMode::Components(components))
1430 }
1431 }
1432
1433 fn read_splice_time(
1434 r: &mut bitreader::BitReader<'_>,
1435 ) -> Result<Option<u64>, SpliceDescriptorErr> {
1436 Ok(if r.read_bool().named("splice_time.time_specified_flag")? {
1437 r.skip(6).named("splice_time.reserved")?; Some(r.read_u64(33).named("splice_time.pts_time")?)
1439 } else {
1440 r.skip(7).named("splice_time.reserved")?; None
1442 })
1443 }
1444
1445 fn read_duration(
1446 r: &mut bitreader::BitReader<'_>,
1447 ) -> Result<SpliceDuration, SpliceDescriptorErr> {
1448 let return_mode = ReturnMode::from_flag(r.read_u8(1).named("break_duration.auto_return")?);
1449 r.skip(6).named("break_duration.reserved")?;
1450 Ok(SpliceDuration {
1451 return_mode,
1452 duration: r.read_u64(33).named("break_duration.duration")?,
1453 })
1454 }
1455}
1456
1457#[cfg(test)]
1458mod tests {
1459 use super::*;
1460 use hex_literal::*;
1461 use matches::*;
1462 use mpeg2ts_reader::demultiplex;
1463 use mpeg2ts_reader::psi;
1464 use mpeg2ts_reader::psi::WholeCompactSyntaxPayloadParser;
1465
1466 mpeg2ts_reader::demux_context!(
1467 NullDemuxContext,
1468 demultiplex::NullPacketFilter<NullDemuxContext>
1469 );
1470 impl NullDemuxContext {
1471 fn do_construct(
1472 &mut self,
1473 _req: demultiplex::FilterRequest<'_, '_>,
1474 ) -> demultiplex::NullPacketFilter<NullDemuxContext> {
1475 unimplemented!();
1476 }
1477 }
1478
1479 struct MockSpliceInsertProcessor;
1480 impl SpliceInfoProcessor for MockSpliceInsertProcessor {
1481 fn process(
1482 &self,
1483 header: SpliceInfoHeader<'_>,
1484 command: SpliceCommand,
1485 descriptors: SpliceDescriptors<'_>,
1486 ) {
1487 assert_eq!(header.encryption_algorithm(), EncryptionAlgorithm::None);
1488 assert_matches!(command, SpliceCommand::SpliceInsert { .. });
1489 for d in &descriptors {
1490 d.unwrap();
1491 }
1492 }
1493 }
1494
1495 #[test]
1496 fn it_works() {
1497 let data = hex!(
1498 "fc302500000000000000fff01405000000017feffe2d142b00fe0123d3080001010100007f157a49"
1499 );
1500 let mut parser = Scte35SectionProcessor::new(MockSpliceInsertProcessor);
1501 let header = psi::SectionCommonHeader::new(&data[..psi::SectionCommonHeader::SIZE]);
1502 let mut ctx = NullDemuxContext::new();
1503 parser.section(&mut ctx, &header, &data[..]);
1504 }
1505
1506 struct MockTimeSignalProcessor;
1507 impl SpliceInfoProcessor for MockTimeSignalProcessor {
1508 fn process(
1509 &self,
1510 header: SpliceInfoHeader<'_>,
1511 command: SpliceCommand,
1512 descriptors: SpliceDescriptors<'_>,
1513 ) {
1514 assert_eq!(header.encryption_algorithm(), EncryptionAlgorithm::None);
1515 assert_matches!(command, SpliceCommand::TimeSignal { .. });
1516 for d in &descriptors {
1517 d.unwrap();
1518 }
1519 }
1520 }
1521
1522 #[test]
1523 fn it_understands_time_signal() {
1524 let data = hex!(
1525 "fc302700000000000000fff00506ff592d03c00011020f43554549000000017fbf000010010112ce0e6b"
1526 );
1527 let mut parser = Scte35SectionProcessor::new(MockTimeSignalProcessor);
1528 let header = psi::SectionCommonHeader::new(&data[..psi::SectionCommonHeader::SIZE]);
1529 let mut ctx = NullDemuxContext::new();
1530 parser.section(&mut ctx, &header, &data[..]);
1531 }
1532
1533 #[test]
1534 fn splice_descriptor() {
1535 let data = [];
1536 assert_matches!(
1537 SpliceDescriptor::parse(&data[..]),
1538 Err(SpliceDescriptorErr::NotEnoughData { .. })
1539 );
1540 let data = hex!("01084D5949440000"); assert_matches!(
1542 SpliceDescriptor::parse(&data[..]),
1543 Err(SpliceDescriptorErr::NotEnoughData { .. })
1544 );
1545 let data = hex!("01034D59494400000003");
1546 assert_matches!(
1547 SpliceDescriptor::parse(&data[..]),
1548 Err(SpliceDescriptorErr::InvalidDescriptorLength { .. })
1549 );
1550 let data = hex!("01084D59494400000003");
1551 assert_matches!(
1552 SpliceDescriptor::parse(&data[..]),
1553 Ok(SpliceDescriptor::Reserved {
1554 tag: 01,
1555 identifier: [0x4D, 0x59, 0x49, 0x44],
1556 private_bytes: _,
1557 })
1558 );
1559
1560 let data = hex!("020f43554549000000017fbf0000100101");
1561 assert_matches!(
1562 SpliceDescriptor::parse(&data[..]),
1563 Ok(SpliceDescriptor::SegmentationDescriptor {
1564 segmentation_event_id: 1,
1565 descriptor_detail: SegmentationDescriptor::Insert {
1566 program_segmentation_flag: true,
1567 segmentation_duration_flag: false,
1568 delivery_not_restricted_flag: true,
1569 delivery_restrictions: DeliveryRestrictionFlags::None,
1570 segmentation_mode: SegmentationMode::Program,
1571 segmentation_duration: None,
1572 segmentation_upid: SegmentationUpid::None,
1573 segmentation_type_id: SegmentationTypeId::ProgramStart,
1574 segment_num: 1,
1575 segments_expected: 1,
1576 sub_segments: None,
1577 }
1578 })
1579 );
1580 }
1581
1582 #[test]
1583 fn segmentation_descriptor() {
1584 let data = hex!("480000ad7f9f0808000000002cb2d79d350200");
1585 let desc = SpliceDescriptor::parse_segmentation_descriptor(&data[..]).unwrap();
1586 match desc {
1587 SpliceDescriptor::SegmentationDescriptor {
1588 descriptor_detail:
1589 SegmentationDescriptor::Insert {
1590 segmentation_upid: SegmentationUpid::TI(ti),
1591 ..
1592 },
1593 ..
1594 } => {
1595 assert_eq!(ti, upid::TI(hex!("000000002cb2d79d").to_vec()));
1597 }
1598 _ => panic!("unexpected {:?}", desc),
1599 };
1600 }
1601
1602 #[test]
1603 fn no_sub_segment_num() {
1604 let data = hex!("480000bf7fcf0000f8fa630d110e054c413330390808000000002e538481340000");
1607 SpliceDescriptor::parse_segmentation_descriptor(&data[..]).unwrap();
1608 }
1609
1610 #[test]
1611 fn too_large_segment_descriptor() {
1612 let data = hex!("480000ad7f9f0808000000002cb2d79d350200000000");
1614 SpliceDescriptor::parse_segmentation_descriptor(&data[..]).unwrap();
1615 }
1616}