1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! Encoding implementation for SpliceInfoSection.
use crate::encoding::{BitWriter, Encodable, EncodingResult};
use crate::types::SpliceInfoSection;
impl SpliceInfoSection {
/// Calculate the correct section_length for encoding.
fn calculate_section_length(&self) -> u16 {
// Section length is from the byte after section_length to the end (including CRC)
// Total size minus the first 3 bytes (table_id + section_syntax_indicator/private_indicator/sap_type + section_length)
// The encoded_size method calculates total size, so we subtract 3
(self.encoded_size() - 3) as u16
}
/// Calculate the correct splice_command_length for encoding.
fn calculate_splice_command_length(&self) -> u16 {
self.splice_command.encoded_size() as u16
}
/// Encode all fields except the CRC-32.
fn encode_without_crc(&self, writer: &mut BitWriter) -> EncodingResult<()> {
// Table ID (8 bits)
writer.write_bits(self.table_id as u64, 8)?;
// Section syntax indicator (1 bit)
writer.write_bits(self.section_syntax_indicator as u64, 1)?;
// Private indicator (1 bit)
writer.write_bits(self.private_indicator as u64, 1)?;
// SAP type (2 bits)
writer.write_bits(self.sap_type as u64, 2)?;
// Section length (12 bits) - calculate the correct value
let section_length = self.calculate_section_length();
writer.write_bits(section_length as u64, 12)?;
// Protocol version (8 bits)
writer.write_bits(self.protocol_version as u64, 8)?;
// Encrypted packet (1 bit)
writer.write_bits(self.encrypted_packet as u64, 1)?;
// Encryption algorithm (6 bits)
writer.write_bits(self.encryption_algorithm as u64, 6)?;
// PTS adjustment (33 bits)
writer.write_bits(self.pts_adjustment & 0x1FFFFFFFF, 33)?;
// CW index (8 bits)
writer.write_bits(self.cw_index as u64, 8)?;
// Tier (12 bits)
writer.write_bits(self.tier as u64 & 0xFFF, 12)?;
// Splice command length (12 bits) - calculate the correct value
let splice_command_length = self.calculate_splice_command_length();
writer.write_bits(splice_command_length as u64, 12)?;
// Splice command type (8 bits)
writer.write_bits(self.splice_command_type as u64, 8)?;
// Encode splice command
self.splice_command.encode(writer)?;
// Descriptor loop length (16 bits) - calculate the correct value
let mut descriptor_loop_length = 0u16;
for descriptor in &self.splice_descriptors {
descriptor_loop_length += descriptor.encoded_size() as u16;
}
writer.write_bits(descriptor_loop_length as u64, 16)?;
// Encode splice descriptors
for descriptor in &self.splice_descriptors {
descriptor.encode(writer)?;
}
// Alignment stuffing
if !self.alignment_stuffing_bits.is_empty() {
writer.write_bytes(&self.alignment_stuffing_bits)?;
}
// E_CRC_32 if encrypted
if let Some(e_crc) = self.e_crc_32 {
writer.write_bits(e_crc as u64, 32)?;
}
Ok(())
}
}
impl Encodable for SpliceInfoSection {
fn encode(&self, writer: &mut BitWriter) -> EncodingResult<()> {
// Encode everything except CRC
self.encode_without_crc(writer)?;
// CRC-32 (placeholder for now, will be calculated later)
writer.write_bits(self.crc_32 as u64, 32)?;
Ok(())
}
fn encoded_size(&self) -> usize {
// Fixed header size (up to and including splice_command_type)
// 112 bits = 14 bytes exactly
let mut size = 14; // bytes
// Splice command size
size += self.splice_command.encoded_size();
// Descriptor loop length field
size += 2;
// Descriptors
for descriptor in &self.splice_descriptors {
size += descriptor.encoded_size();
}
// Alignment stuffing
size += self.alignment_stuffing_bits.len();
// E_CRC_32 if present
if self.e_crc_32.is_some() {
size += 4;
}
// CRC_32
size += 4;
size
}
}
#[cfg(feature = "crc-validation")]
use crate::encoding::CrcEncodable;
#[cfg(feature = "crc-validation")]
impl CrcEncodable for SpliceInfoSection {
fn encode_with_crc(&self) -> EncodingResult<Vec<u8>> {
use crate::crc::calculate_crc;
// Encode everything except the CRC field
let mut writer = BitWriter::with_capacity(self.encoded_size());
// Encode all fields up to CRC
self.encode_without_crc(&mut writer)?;
// Get the buffer and calculate CRC
let mut buffer = writer.finish();
if let Some(crc) = calculate_crc(&buffer) {
// Append the calculated CRC
buffer.extend_from_slice(&crc.to_be_bytes());
} else {
// If CRC calculation is not available, use the stored CRC
buffer.extend_from_slice(&self.crc_32.to_be_bytes());
}
Ok(buffer)
}
}
#[cfg(feature = "base64")]
use crate::encoding::Base64Encodable;
#[cfg(feature = "base64")]
impl Base64Encodable for SpliceInfoSection {}