Can encode SpliceNull, first test pass

This commit is contained in:
Rafael Caricio 2022-05-01 11:45:26 +02:00
parent 5e9522b845
commit e4ccc470a6
Signed by: rafaelcaricio
GPG key ID: 3C86DBCE8E93C947
4 changed files with 179 additions and 141 deletions

View file

@ -1,133 +0,0 @@
use crate::{CueError, TransportPacketWrite};
use std::io::Write;
pub trait SpliceDescriptor {
fn splice_descriptor_tag(&self) -> u8;
}
struct SegmentationDescriptor {
identifier: u32,
segmentation_event_id: u32,
segmentation_event_cancel_indicator: bool,
program_segmentation: Vec<Component>,
delivery_restricted: Option<DeliveryRestriction>,
segmentation_duration: Option<u64>,
segmentation_upid: SegmentationUpid,
}
impl TransportPacketWrite for SegmentationDescriptor {
fn write_to<W>(&self, buffer: &mut W) -> Result<(), CueError>
where
W: Write,
{
todo!()
}
}
impl SpliceDescriptor for SegmentationDescriptor {
fn splice_descriptor_tag(&self) -> u8 {
SpliceDescriptorTag::Segmentation.into()
}
}
struct DeliveryRestriction {
web_delivery_allowed_flag: bool,
no_regional_blackout_flag: bool,
archive_allowed_flag: bool,
device_restrictions: DeviceRestrictions,
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum SpliceDescriptorTag {
Avail,
DTMF,
Segmentation,
Time,
Audio,
Reserved(u8),
DVB(u8),
}
impl From<u8> for SpliceDescriptorTag {
fn from(value: u8) -> Self {
match value {
0x0 => SpliceDescriptorTag::Avail,
0x1 => SpliceDescriptorTag::DTMF,
0x2 => SpliceDescriptorTag::Segmentation,
0x3 => SpliceDescriptorTag::Time,
0x4 => SpliceDescriptorTag::Audio,
0x5..=0xEF => SpliceDescriptorTag::Reserved(value),
0xF0..=0xFF => SpliceDescriptorTag::DVB(value),
}
}
}
impl From<SpliceDescriptorTag> for u8 {
fn from(value: SpliceDescriptorTag) -> Self {
match value {
SpliceDescriptorTag::Avail => 0x0,
SpliceDescriptorTag::DTMF => 0x1,
SpliceDescriptorTag::Segmentation => 0x2,
SpliceDescriptorTag::Time => 0x3,
SpliceDescriptorTag::Audio => 0x4,
SpliceDescriptorTag::Reserved(value) => value,
SpliceDescriptorTag::DVB(value) => value,
}
}
}
enum DeviceRestrictions {
RestrictGroup0 = 0x00,
RestrictGroup1 = 0x01,
RestrictGroup2 = 0x10,
None = 0x11,
}
enum SegmentationUpidType {
NotUsed,
UserDefinedDeprecated,
ISCI,
AdID,
UMID,
ISANDeprecated,
ISAN,
TID,
TI,
ADI,
EIDR,
ATSCContentIdentifier,
MPU,
MID,
ADSInformation,
URI,
UUID,
SCR,
Reserved,
}
enum SegmentationUpid {
NotUsed,
UserDefinedDeprecated,
ISCI,
AdID,
UMID,
ISANDeprecated,
ISAN,
TID,
TI,
ADI,
EIDR,
ATSCContentIdentifier,
MPU,
MID,
ADSInformation,
URI,
UUID,
SCR,
Reserved,
}
struct Component {
component_tag: u8,
pts_offset: u64,
}

84
src/descriptors/mod.rs Normal file
View file

@ -0,0 +1,84 @@
mod segmentation;
use crate::{CueError, TransportPacketWrite};
use std::io;
pub use segmentation::*;
pub enum SpliceDescriptor {
Avail,
DTMF,
Segmentation(SegmentationDescriptor),
Time,
Audio,
Unknown(u8, u32, Vec<u8>),
}
impl SpliceDescriptor {
fn splice_descriptor_tag(&self) -> u8 {
use SpliceDescriptor::*;
match self {
Segmentation(_) => SpliceDescriptorTag::Segmentation.into(),
Avail => SpliceDescriptorTag::Avail.into(),
DTMF => SpliceDescriptorTag::DTMF.into(),
Time => SpliceDescriptorTag::Time.into(),
Audio => SpliceDescriptorTag::Audio.into(),
Unknown(tag, _, _) => *tag,
}
}
}
impl TransportPacketWrite for SpliceDescriptor {
fn write_to<W>(&self, buffer: &mut W) -> Result<(), CueError>
where
W: io::Write,
{
match self {
SpliceDescriptor::Avail => unimplemented!(),
SpliceDescriptor::DTMF => unimplemented!(),
SpliceDescriptor::Segmentation(segmentation) => segmentation.write_to(buffer),
SpliceDescriptor::Time => unimplemented!(),
SpliceDescriptor::Audio => unimplemented!(),
SpliceDescriptor::Unknown(_, _, _) => unimplemented!(),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum SpliceDescriptorTag {
Avail,
DTMF,
Segmentation,
Time,
Audio,
Reserved(u8),
DVB(u8),
}
impl From<u8> for SpliceDescriptorTag {
fn from(value: u8) -> Self {
match value {
0x0 => SpliceDescriptorTag::Avail,
0x1 => SpliceDescriptorTag::DTMF,
0x2 => SpliceDescriptorTag::Segmentation,
0x3 => SpliceDescriptorTag::Time,
0x4 => SpliceDescriptorTag::Audio,
0x5..=0xEF => SpliceDescriptorTag::Reserved(value),
_ => SpliceDescriptorTag::DVB(value),
}
}
}
impl From<SpliceDescriptorTag> for u8 {
fn from(value: SpliceDescriptorTag) -> Self {
match value {
SpliceDescriptorTag::Avail => 0x0,
SpliceDescriptorTag::DTMF => 0x1,
SpliceDescriptorTag::Segmentation => 0x2,
SpliceDescriptorTag::Time => 0x3,
SpliceDescriptorTag::Audio => 0x4,
SpliceDescriptorTag::Reserved(value) => value,
SpliceDescriptorTag::DVB(value) => value,
}
}
}

View file

@ -0,0 +1,84 @@
use crate::{CueError, TransportPacketWrite};
use std::io;
pub struct SegmentationDescriptor {
identifier: u32,
segmentation_event_id: u32,
segmentation_event_cancel_indicator: bool,
program_segmentation: Vec<Component>,
delivery_restricted: Option<DeliveryRestriction>,
segmentation_duration: Option<u64>,
segmentation_upid: SegmentationUpid,
}
impl TransportPacketWrite for SegmentationDescriptor {
fn write_to<W>(&self, buffer: &mut W) -> Result<(), CueError>
where
W: io::Write,
{
todo!()
}
}
struct DeliveryRestriction {
web_delivery_allowed_flag: bool,
no_regional_blackout_flag: bool,
archive_allowed_flag: bool,
device_restrictions: DeviceRestrictions,
}
enum DeviceRestrictions {
RestrictGroup0 = 0x00,
RestrictGroup1 = 0x01,
RestrictGroup2 = 0x10,
None = 0x11,
}
enum SegmentationUpidType {
NotUsed,
UserDefinedDeprecated,
ISCI,
AdID,
UMID,
ISANDeprecated,
ISAN,
TID,
TI,
ADI,
EIDR,
ATSCContentIdentifier,
MPU,
MID,
ADSInformation,
URI,
UUID,
SCR,
Reserved,
}
enum SegmentationUpid {
NotUsed,
UserDefinedDeprecated,
ISCI,
AdID,
UMID,
ISANDeprecated,
ISAN,
TID,
TI,
ADI,
EIDR,
ATSCContentIdentifier,
MPU,
MID,
ADSInformation,
URI,
UUID,
SCR,
Reserved,
}
struct Component {
component_tag: u8,
pts_offset: u64,
}

View file

@ -3,6 +3,9 @@ use crate::descriptors::SpliceDescriptor;
use crate::{CueError, TransportPacketWrite};
use bitstream_io::{BigEndian, BitWrite, BitWriter};
use std::io;
use crc::{Crc, Algorithm, CRC_32_MPEG_2};
pub const MPEG_2: Crc<u32> = Crc::<u32>::new(&CRC_32_MPEG_2);
pub struct SpliceInfoSection<C>
where
@ -33,7 +36,7 @@ where
splice_command: C,
descriptors: Vec<Box<dyn SpliceDescriptor>>,
descriptors: Vec<SpliceDescriptor>,
}
impl<C> SpliceInfoSection<C>
@ -51,7 +54,7 @@ where
encryption_algorithm: EncryptionAlgorithm::NotEncrypted,
pts_adjustment: 0,
cw_index: 0,
tier: 0,
tier: 0xFFF,
splice_command,
descriptors: Vec::new(),
}
@ -91,7 +94,7 @@ impl From<u8> for EncryptionAlgorithm {
0x02 => EncryptionAlgorithm::DESCBCMode,
0x03 => EncryptionAlgorithm::TripleDESEDE3ECBMode,
0x04..=0x1F => EncryptionAlgorithm::Reserved(value),
0x20..=0xFF => EncryptionAlgorithm::Private(value),
_ => EncryptionAlgorithm::Private(value),
}
}
}
@ -123,9 +126,9 @@ where
// Write the descriptors to a temporary buffer
let mut descriptor_data = Vec::new();
// for descriptor in &self.descriptors {
// descriptor.write_to(&mut descriptor_data)?;
// }
for descriptor in &self.descriptors {
descriptor.write_to(&mut descriptor_data)?;
}
// Start writing the final output to a temporary buffer
let mut data = Vec::new();
@ -168,7 +171,7 @@ where
}
// TODO: Calculate CRC32. Use the data information
// crc32:
buffer.write(32, 0)?;
buffer.write(32, MPEG_2.checksum(data.as_slice()))?;
buffer.flush()?;
Ok(())
@ -184,6 +187,6 @@ mod tests {
fn write_null_splice() {
let splice = SpliceInfoSection::new(SpliceNull::new());
assert_eq!(splice.as_base64().unwrap(), "".to_string());
assert_eq!(splice.as_base64().unwrap(), "/DARAAAAAAAAAP/wAAAAAHpPv/8=".to_string());
}
}