Compare commits
No commits in common. "use-deku" and "main" have entirely different histories.
5 changed files with 2 additions and 318 deletions
|
@ -7,9 +7,8 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = { version = "0.13", default-features = false, features = ["alloc"] }
|
base64 = "0.13"
|
||||||
bitstream-io = "1.3"
|
bitstream-io = "1.3"
|
||||||
deku = { version = "0.13", default-features = false, features = ["alloc"] }
|
|
||||||
crc = "3.0"
|
crc = "3.0"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
|
@ -20,4 +19,3 @@ ascii = "1"
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
assert-json-diff = "2"
|
assert-json-diff = "2"
|
||||||
hexlit = "0.5"
|
|
||||||
|
|
286
src/data.rs
286
src/data.rs
|
@ -1,286 +0,0 @@
|
||||||
use ascii::AsciiString;
|
|
||||||
use deku::prelude::*;
|
|
||||||
use crate::{DeviceRestrictions};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
#[deku(endian = "big", type = "u8", bits = "1")]
|
|
||||||
pub(crate) enum SpliceTime {
|
|
||||||
#[deku(id = "1")]
|
|
||||||
TimeSpecified {
|
|
||||||
#[deku(bits = "6", assert_eq = "0x3f", update = "0x3f")]
|
|
||||||
_reserved: u8,
|
|
||||||
|
|
||||||
#[deku(bits = "33")]
|
|
||||||
pts_time: u64,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[deku(id = "0")]
|
|
||||||
NoTimeSpecified {
|
|
||||||
#[deku(bits = "7", assert_eq = "0x7f", update = "0x7f")]
|
|
||||||
_reserved: u8,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SpliceTime {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::NoTimeSpecified { _reserved: 0x7f }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpliceTime {
|
|
||||||
fn new(pts_time: u64) -> Self {
|
|
||||||
Self::TimeSpecified {
|
|
||||||
_reserved: 0x3f,
|
|
||||||
pts_time,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
#[deku(type = "u8")]
|
|
||||||
pub(crate) enum SpliceDescriptor {
|
|
||||||
#[deku(id = "0x02")]
|
|
||||||
SegmentationDescriptor(SegmentationDescriptor),
|
|
||||||
|
|
||||||
#[deku(id_pat = "_")]
|
|
||||||
Template(GenericDescriptor),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpliceDescriptor {
|
|
||||||
pub(crate) fn update(&mut self) -> Result<(), deku::DekuError> {
|
|
||||||
use SpliceDescriptor::*;
|
|
||||||
match self {
|
|
||||||
Template(s) => s.update(),
|
|
||||||
SegmentationDescriptor(s) => s.update(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
#[deku(endian = "big")]
|
|
||||||
pub(crate) struct GenericDescriptor {
|
|
||||||
id: u8,
|
|
||||||
|
|
||||||
#[deku(update = "self.private_bytes.len() + 2")]
|
|
||||||
descriptor_length: u8,
|
|
||||||
|
|
||||||
identifier: u32,
|
|
||||||
|
|
||||||
#[deku(count = "descriptor_length - 2")]
|
|
||||||
private_bytes: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
pub(crate) struct SegmentationDescriptor {
|
|
||||||
descriptor_length: u8, // TODO: need to calculate by hand the size based in `self.*`
|
|
||||||
|
|
||||||
identifier: u32,
|
|
||||||
|
|
||||||
segmentation_event_id: u32,
|
|
||||||
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
segmentation_event_cancel_indicator: bool,
|
|
||||||
|
|
||||||
#[deku(bits = "7", assert_eq = "0x7f", update = "0x7f")]
|
|
||||||
_reserved: u8,
|
|
||||||
|
|
||||||
#[deku(
|
|
||||||
skip,
|
|
||||||
cond = "*segmentation_event_cancel_indicator == false",
|
|
||||||
default = "None"
|
|
||||||
)]
|
|
||||||
segmentation: Option<Segmentation>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
pub(crate) struct Segmentation {
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
program_segmentation_flag: bool,
|
|
||||||
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
segmentation_duration_flag: bool,
|
|
||||||
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
delivery_not_restricted_flag: bool,
|
|
||||||
|
|
||||||
#[deku(cond = "*delivery_not_restricted_flag == false")]
|
|
||||||
delivery_restriction: Option<DeliveryRestriction>,
|
|
||||||
|
|
||||||
#[deku(cond = "*delivery_not_restricted_flag", bits = "5")]
|
|
||||||
_reserved1: Option<u8>,
|
|
||||||
|
|
||||||
#[deku(cond = "*program_segmentation_flag == false")]
|
|
||||||
program_components: Option<ProgramComponents>,
|
|
||||||
|
|
||||||
#[deku(cond = "*segmentation_duration_flag", bits = "40")]
|
|
||||||
segmentation_duration: u64,
|
|
||||||
|
|
||||||
segmentation_upid: SegmentationUpid,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
#[deku(type = "u8")]
|
|
||||||
#[non_exhaustive]
|
|
||||||
pub enum SegmentationUpid {
|
|
||||||
#[deku(id = "0x00")]
|
|
||||||
NotUsed,
|
|
||||||
|
|
||||||
#[deku(id = "0x01")]
|
|
||||||
UserDefinedDeprecated(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x02")]
|
|
||||||
ISCI(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x03")]
|
|
||||||
AdID(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x04")]
|
|
||||||
UMID(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x05")]
|
|
||||||
ISANDeprecated(u64),
|
|
||||||
|
|
||||||
#[deku(id = "0x06")]
|
|
||||||
ISAN(u128),
|
|
||||||
|
|
||||||
#[deku(id = "0x07")]
|
|
||||||
TID(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x08")]
|
|
||||||
AiringID(u64),
|
|
||||||
|
|
||||||
#[deku(id = "0x09")]
|
|
||||||
ADI(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x0a")]
|
|
||||||
EIDR(u128),
|
|
||||||
|
|
||||||
#[deku(id = "0x0b")]
|
|
||||||
ATSCContentIdentifier(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x0c")]
|
|
||||||
MPU,
|
|
||||||
|
|
||||||
#[deku(id = "0x0d")]
|
|
||||||
MID,
|
|
||||||
|
|
||||||
#[deku(id = "0x0e")]
|
|
||||||
ADSInformation(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x0f")]
|
|
||||||
URI(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id = "0x10")]
|
|
||||||
UUID(u128),
|
|
||||||
|
|
||||||
#[deku(id = "0x11")]
|
|
||||||
SCR(AsciiString),
|
|
||||||
|
|
||||||
#[deku(id_pat = "_")]
|
|
||||||
Reserved(u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
pub(crate) struct ProgramComponents {
|
|
||||||
#[deku(update = "self.components.len()")]
|
|
||||||
component_count: u8,
|
|
||||||
|
|
||||||
#[deku(count = "component_count")]
|
|
||||||
components: Vec<SegmentationDescriptorComponent>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
pub(crate) struct SegmentationDescriptorComponent {
|
|
||||||
component_tag: u8,
|
|
||||||
|
|
||||||
#[deku(bits = "7")]
|
|
||||||
_reserved: u8,
|
|
||||||
|
|
||||||
#[deku(bits = "33")]
|
|
||||||
pts_offset: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)]
|
|
||||||
pub(crate) struct DeliveryRestriction {
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
web_delivery_allowed_flag: bool,
|
|
||||||
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
no_regional_blackout_flag: bool,
|
|
||||||
|
|
||||||
#[deku(bits = "1")]
|
|
||||||
archive_allowed_flag: bool,
|
|
||||||
|
|
||||||
device_restrictions: DeviceRestrictions,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn write_splice_time() {
|
|
||||||
let st = SpliceTime::default();
|
|
||||||
let data: Vec<u8> = st.try_into().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(hex::encode(data.as_slice()), "7f");
|
|
||||||
|
|
||||||
// Check update is defined for missing value in field
|
|
||||||
let mut st = SpliceTime::NoTimeSpecified {
|
|
||||||
_reserved: 0
|
|
||||||
};
|
|
||||||
st.update().unwrap();
|
|
||||||
|
|
||||||
let data: Vec<u8> = st.try_into().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(hex::encode(data.as_slice()), "7f");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn write_splice_time_with_pts_time() {
|
|
||||||
let st = SpliceTime::new(0x072bd0050);
|
|
||||||
let encoded: Vec<u8> = st.try_into().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(hex::encode(encoded.as_slice()), "fe72bd0050");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn read_splice_time_with_pts_time() {
|
|
||||||
let data = hex::decode("fe72bd0050").unwrap();
|
|
||||||
let st = SpliceTime::try_from(data.as_slice()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(st, SpliceTime::new(0x072bd0050));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn write_generic_descriptor() {
|
|
||||||
let mut sd = SpliceDescriptor::Template(GenericDescriptor {
|
|
||||||
id: 0xff,
|
|
||||||
descriptor_length: 0,
|
|
||||||
identifier: 0x43554549,
|
|
||||||
private_bytes: vec![0x01],
|
|
||||||
});
|
|
||||||
|
|
||||||
sd.update().unwrap();
|
|
||||||
|
|
||||||
let data: Vec<u8> = sd.try_into().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(hex::encode(data.as_slice()), "ff034355454901");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn read_generic_descriptor() {
|
|
||||||
let data = hex::decode("ff034355454901").unwrap();
|
|
||||||
let sd = SpliceDescriptor::try_from(data.as_slice()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sd,
|
|
||||||
SpliceDescriptor::Template(GenericDescriptor {
|
|
||||||
id: 0xff,
|
|
||||||
descriptor_length: 3,
|
|
||||||
identifier: 0x43554549,
|
|
||||||
private_bytes: vec![0x01]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
use deku::prelude::*;
|
|
||||||
use crate::{BytesWritten, ClockTimeExt};
|
use crate::{BytesWritten, ClockTimeExt};
|
||||||
use ascii::AsciiString;
|
use ascii::AsciiString;
|
||||||
use bitstream_io::{BigEndian, BitRecorder, BitWrite, BitWriter};
|
use bitstream_io::{BigEndian, BitRecorder, BitWrite, BitWriter};
|
||||||
|
@ -253,10 +252,9 @@ impl SpliceDescriptorExt for SegmentationDescriptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, DekuRead, DekuWrite)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[deku(type="u8", bits="2")]
|
|
||||||
pub enum DeviceRestrictions {
|
pub enum DeviceRestrictions {
|
||||||
/// This Segment is restricted for a class of devices defined by an out of band message that
|
/// This Segment is restricted for a class of devices defined by an out of band message that
|
||||||
/// describes which devices are excluded.
|
/// describes which devices are excluded.
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::time::Duration;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod data;
|
|
||||||
mod descriptors;
|
mod descriptors;
|
||||||
mod info;
|
mod info;
|
||||||
mod time;
|
mod time;
|
||||||
|
|
25
src/time.rs
25
src/time.rs
|
@ -80,28 +80,3 @@ where
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn encode_time_signal() {
|
|
||||||
let mut st = SpliceTime::default();
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
|
||||||
st.write_to(&mut data).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(hex::encode(data.as_slice()), "7f")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn encode_time_signal_with_time() {
|
|
||||||
let mut st = SpliceTime::from(0x072bd0050);
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
|
||||||
st.write_to(&mut data).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(hex::encode(data.as_slice()), "fe72bd0050")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue