1use std::io::{Read, Seek, SeekFrom};
4
5use byteorder::{LittleEndian, ReadBytesExt};
6
7use crate::error::{DecoderError, Result};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Guid(pub [u8; 16]);
13
14impl Guid {
15 pub fn read<R: Read>(r: &mut R) -> Result<Self> {
16 let mut buf = [0u8; 16];
17 r.read_exact(&mut buf)?;
18 Ok(Guid(buf))
19 }
20}
21
22impl std::fmt::Display for Guid {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 let b = &self.0;
25 write!(
26 f,
27 "{:02X}{:02X}{:02X}{:02X}-{:02X}{:02X}-{:02X}{:02X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
28 b[3],
29 b[2],
30 b[1],
31 b[0],
32 b[5],
33 b[4],
34 b[7],
35 b[6],
36 b[8],
37 b[9],
38 b[10],
39 b[11],
40 b[12],
41 b[13],
42 b[14],
43 b[15]
44 )
45 }
46}
47
48pub const GUID_ASF_HEADER: Guid = Guid([
50 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C,
51]);
52pub const GUID_ASF_DATA: Guid = Guid([
53 0x36, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C,
54]);
55pub const GUID_FILE_PROPERTIES: Guid = Guid([
56 0xA1, 0xDC, 0xAB, 0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65,
57]);
58pub const GUID_STREAM_PROPERTIES: Guid = Guid([
59 0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65,
60]);
61pub const GUID_STREAM_TYPE_VIDEO: Guid = Guid([
62 0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B,
63]);
64pub const GUID_STREAM_TYPE_AUDIO: Guid = Guid([
65 0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B,
66]);
67
68#[derive(Debug)]
71pub struct ObjectHeader {
72 pub guid: Guid,
73 pub size: u64,
74}
75
76impl ObjectHeader {
77 pub fn read<R: Read>(r: &mut R) -> Result<Self> {
78 let guid = Guid::read(r)?;
79 let size = r.read_u64::<LittleEndian>()?;
80 if size < 24 {
81 return Err(DecoderError::InvalidData("ASF object size < 24".into()));
82 }
83 Ok(Self { guid, size })
84 }
85
86 pub fn payload_size(&self) -> u64 {
87 self.size - 24
88 }
89}
90
91#[derive(Debug, Clone)]
94pub struct VideoStreamInfo {
95 pub stream_number: u8,
96 pub width: u32,
97 pub height: u32,
98 pub codec_four_cc: [u8; 4],
99 pub extra_data: Vec<u8>,
100}
101
102#[derive(Debug, Clone)]
103pub struct AudioStreamInfo {
104 pub stream_number: u8,
105 pub format_tag: u16,
106 pub channels: u16,
107 pub sample_rate: u32,
108 pub bit_rate: u32,
109 pub block_align: u16,
110 pub bits_per_sample: u16,
111 pub extra_data: Vec<u8>,
112 pub ds_span: u8,
115 pub ds_packet_size: u16,
116 pub ds_chunk_size: u16,
117}
118
119#[derive(Debug, Clone)]
122pub struct AsfPayload {
123 pub stream_number: u8,
124 pub object_id: u32,
125 pub obj_offset: u32,
126 pub obj_size: u32,
127 pub pts_ms: u32,
128 pub duration_ms: u16,
129 pub is_key_frame: bool,
130 pub data: Vec<u8>,
131}
132
133#[derive(Debug, Default, Clone)]
134struct AsfStreamState {
135 pkt: Vec<u8>,
136 frag_offset_sum: usize,
137 pkt_clean: bool,
138 seq: u32,
139 pts_ms: u32,
140 is_key: bool,
141}
142
143#[derive(Debug, Clone, Copy, Default)]
144struct AsfAudioDescramble {
145 span: u8,
146 packet_size: u16,
147 chunk_size: u16,
148}
149
150pub struct AsfFile {
153 pub video_streams: Vec<VideoStreamInfo>,
154 pub audio_streams: Vec<AudioStreamInfo>,
155
156 pub data_offset: u64,
157 pub packet_count: u64,
158
159 pub packet_size: u32, pub min_packet_size: u32, pub preroll_ms: u32, pub play_duration_ms: Option<u64>,
164
165 is_audio_stream: [bool; 128],
166 audio_descramble: [AsfAudioDescramble; 128],
167
168 streams: [AsfStreamState; 128],
170}
171
172impl AsfFile {
173 pub fn open<R: Read + Seek>(reader: &mut R) -> Result<Self> {
175 let hdr = ObjectHeader::read(reader)?;
176 if hdr.guid != GUID_ASF_HEADER {
177 return Err(DecoderError::InvalidData("Not an ASF file".into()));
178 }
179
180 let _num_headers = reader.read_u32::<LittleEndian>()?;
181 let _reserved1 = reader.read_u8()?;
182 let _reserved2 = reader.read_u8()?;
183
184 let mut video_streams = Vec::new();
185 let mut audio_streams = Vec::new();
186 let mut is_audio_stream = [false; 128];
187 let mut audio_descramble = std::array::from_fn(|_| AsfAudioDescramble::default());
188
189 let mut packet_count = 0u64;
190 let mut min_pktsize = 0u32;
191 let mut max_pktsize = 0u32;
192 let mut preroll_ms = 0u32;
193 let mut play_time_100ns = 0u64;
194
195 let header_end = hdr.size;
196 let mut pos = 24u64 + 4 + 1 + 1;
197
198 while pos < header_end {
199 let obj = ObjectHeader::read(reader)?;
200 let obj_end = pos + obj.size;
201
202 if obj.guid == GUID_FILE_PROPERTIES {
203 reader.seek(SeekFrom::Current(16 + 8 + 8))?; packet_count = reader.read_u64::<LittleEndian>()?; play_time_100ns = reader.read_u64::<LittleEndian>()?;
207 let _send_time = reader.read_u64::<LittleEndian>()?;
208
209 preroll_ms = reader.read_u32::<LittleEndian>()?;
211 let _preroll_hi_ignored = reader.read_u32::<LittleEndian>()?;
212
213 let _flags = reader.read_u32::<LittleEndian>()?;
214 min_pktsize = reader.read_u32::<LittleEndian>()?;
215 max_pktsize = reader.read_u32::<LittleEndian>()?;
216 let _max_bitrate = reader.read_u32::<LittleEndian>()?;
217 } else if obj.guid == GUID_STREAM_PROPERTIES {
218 let stream_type = Guid::read(reader)?;
219 let _error_correct = Guid::read(reader)?;
220 let _time_offset = reader.read_u64::<LittleEndian>()?;
221 let type_specific_len = reader.read_u32::<LittleEndian>()? as usize;
222 let _err_correct_len = reader.read_u32::<LittleEndian>()?;
223 let flags = reader.read_u16::<LittleEndian>()?;
224 let stream_number = (flags & 0x7F) as u8;
225 let _reserved = reader.read_u32::<LittleEndian>()?;
226
227 if stream_type == GUID_STREAM_TYPE_VIDEO {
228 let _enc_width = reader.read_u32::<LittleEndian>()?;
229 let _enc_height = reader.read_u32::<LittleEndian>()?;
230 reader.read_u8()?;
231 let fmt_data_size = reader.read_u16::<LittleEndian>()? as usize;
232
233 let _bi_size = reader.read_u32::<LittleEndian>()?;
234 let width = reader.read_u32::<LittleEndian>()?;
235 let height_i = reader.read_i32::<LittleEndian>()?;
236 let height = height_i.unsigned_abs();
237 let _planes = reader.read_u16::<LittleEndian>()?;
238 let _bit_count = reader.read_u16::<LittleEndian>()?;
239 let mut four_cc = [0u8; 4];
240 reader.read_exact(&mut four_cc)?;
241 reader.seek(SeekFrom::Current(20))?;
242
243 let extra_len = fmt_data_size.saturating_sub(40);
244 let mut extra_data = vec![0u8; extra_len];
245 reader.read_exact(&mut extra_data)?;
246
247 video_streams.push(VideoStreamInfo {
248 stream_number,
249 width,
250 height,
251 codec_four_cc: four_cc,
252 extra_data,
253 });
254 } else if stream_type == GUID_STREAM_TYPE_AUDIO {
255 is_audio_stream[stream_number as usize] = true;
256
257 let format_tag = reader.read_u16::<LittleEndian>()?;
258 let channels = reader.read_u16::<LittleEndian>()?;
259 let sample_rate = reader.read_u32::<LittleEndian>()?;
260 let bit_rate = reader.read_u32::<LittleEndian>()? * 8; let block_align = reader.read_u16::<LittleEndian>()?;
262 let bits_per_sample = reader.read_u16::<LittleEndian>()?;
263
264 let (cb_size, base_len) = if type_specific_len >= 18 {
265 (reader.read_u16::<LittleEndian>()? as usize, 18usize)
266 } else {
267 (0usize, 16usize)
268 };
269
270 let mut extra_data = vec![0u8; cb_size];
271 if cb_size != 0 {
272 reader.read_exact(&mut extra_data)?;
273 }
274
275 let consumed = base_len + cb_size;
276 let remain = type_specific_len.saturating_sub(consumed);
277 if remain != 0 {
278 reader.seek(SeekFrom::Current(remain as i64))?;
279 }
280
281 let mut ds_span: u8 = 0;
282 let mut ds_packet_size: u16 = 0;
283 let mut ds_chunk_size: u16 = 0;
284 let pos2 = reader.stream_position()?;
285 if (obj_end as i128) - (pos2 as i128) >= 8 {
286 ds_span = reader.read_u8()?;
287 ds_packet_size = reader.read_u16::<LittleEndian>()?;
288 ds_chunk_size = reader.read_u16::<LittleEndian>()?;
289 let _ds_data_size = reader.read_u16::<LittleEndian>()?;
290 let _ds_silence = reader.read_u8()?;
291
292 if ds_span > 1
293 && (ds_chunk_size == 0
294 || (ds_packet_size / ds_chunk_size) <= 1
295 || !ds_packet_size.is_multiple_of(ds_chunk_size))
296 {
297 ds_span = 0;
298 }
299 }
300
301 audio_descramble[stream_number as usize] = AsfAudioDescramble {
302 span: ds_span,
303 packet_size: ds_packet_size,
304 chunk_size: ds_chunk_size,
305 };
306
307 audio_streams.push(AudioStreamInfo {
308 stream_number,
309 format_tag,
310 channels,
311 sample_rate,
312 bit_rate,
313 block_align,
314 bits_per_sample,
315 extra_data,
316 ds_span,
317 ds_packet_size,
318 ds_chunk_size,
319 });
320 } else {
321 reader.seek(SeekFrom::Current(type_specific_len as i64))?;
322 }
323 }
324
325 pos = obj_end;
326 reader.seek(SeekFrom::Start(obj_end))?;
327 }
328
329 let data_obj = ObjectHeader::read(reader)?;
330 if data_obj.guid != GUID_ASF_DATA {
331 return Err(DecoderError::InvalidData(
332 "Expected ASF Data Object after header".into(),
333 ));
334 }
335
336 reader.seek(SeekFrom::Current(16 + 8 + 2))?;
338 let data_offset = reader.stream_position()?;
339
340 if max_pktsize == 0 {
341 return Err(DecoderError::InvalidData("ASF max packet size is 0".into()));
342 }
343
344 Ok(Self {
345 video_streams,
346 audio_streams,
347 data_offset,
348 packet_count,
349 packet_size: max_pktsize,
350 min_packet_size: min_pktsize,
351 preroll_ms,
352 play_duration_ms: (play_time_100ns > 0)
353 .then_some((play_time_100ns / 10_000).saturating_sub(preroll_ms as u64)),
354 is_audio_stream,
355 audio_descramble,
356 streams: std::array::from_fn(|_| AsfStreamState::default()),
357 })
358 }
359
360 fn descramble_audio_if_needed(&self, stream_num: u8, data: Vec<u8>) -> Vec<u8> {
361 let ds = self.audio_descramble[stream_num as usize];
362 if ds.span <= 1 {
363 return data;
364 }
365 let span = ds.span as usize;
366 let packet_size = ds.packet_size as usize;
367 let chunk_size = ds.chunk_size as usize;
368 if chunk_size == 0 {
369 return data;
370 }
371 if data.len() != packet_size.saturating_mul(span) {
372 return data;
373 }
374 if !packet_size.is_multiple_of(chunk_size) {
375 return data;
376 }
377 let chunks_per_packet = packet_size / chunk_size;
378 if chunks_per_packet <= 1 {
379 return data;
380 }
381
382 let mut out = vec![0u8; data.len()];
384 let mut offset: usize = 0;
385 while offset < data.len() {
386 let off = offset / chunk_size;
387 let row = off / span;
388 let col = off % span;
389 let idx = row + col * chunks_per_packet;
390 let src = idx * chunk_size;
391 if src + chunk_size > data.len() || offset + chunk_size > out.len() {
392 return data;
393 }
394 out[offset..offset + chunk_size].copy_from_slice(&data[src..src + chunk_size]);
395 offset += chunk_size;
396 }
397 out
398 }
399
400 #[inline(always)]
401 fn read_2bits_from_buf(buf: &[u8], i: &mut usize, code: u8, def: u32) -> Result<u32> {
402 match code & 3 {
403 0 => Ok(def),
404 1 => {
405 if *i + 1 > buf.len() {
406 return Err(DecoderError::InvalidData("ASF packet truncated".into()));
407 }
408 let v = buf[*i] as u32;
409 *i += 1;
410 Ok(v)
411 }
412 2 => {
413 if *i + 2 > buf.len() {
414 return Err(DecoderError::InvalidData("ASF packet truncated".into()));
415 }
416 let v = u16::from_le_bytes([buf[*i], buf[*i + 1]]) as u32;
417 *i += 2;
418 Ok(v)
419 }
420 3 => {
421 if *i + 4 > buf.len() {
422 return Err(DecoderError::InvalidData("ASF packet truncated".into()));
423 }
424 let v = u32::from_le_bytes([buf[*i], buf[*i + 1], buf[*i + 2], buf[*i + 3]]);
425 *i += 4;
426 Ok(v)
427 }
428 _ => unreachable!(),
429 }
430 }
431
432 pub fn read_packet<R: Read + Seek>(&mut self, reader: &mut R) -> Result<Vec<AsfPayload>> {
436 let pkt_size = self.packet_size as usize;
437 if pkt_size == 0 {
438 return Err(DecoderError::InvalidData("ASF packet size is 0".into()));
439 }
440
441 let mut buf = vec![0u8; pkt_size];
442 match reader.read_exact(&mut buf) {
443 Ok(()) => {}
444 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
445 return Err(DecoderError::EndOfStream);
446 }
447 Err(e) => return Err(DecoderError::Io(e)),
448 }
449
450 const FRAME_HEADER_SIZE: i32 = 6; let mut out: Vec<AsfPayload> = Vec::new();
453
454 let mut i: usize = 0;
456
457 if buf.len() >= 3 && buf[0] == 0x82 && buf[1] == 0 && buf[2] == 0 {
460 i = 3;
461 } else if (buf[0] & 0x80) != 0 {
462 let ec_len = (buf[0] & 0x0F) as usize;
463 i = 1 + ec_len;
464 if i > buf.len() {
465 return Ok(out);
467 }
468 }
469
470 if i + 2 > buf.len() {
471 return Ok(out);
472 }
473 let packet_flags = buf[i];
474 let packet_property = buf[i + 1];
475 i += 2;
476
477 let packet_length =
479 Self::read_2bits_from_buf(&buf, &mut i, packet_flags >> 5, self.packet_size)? as u32;
480 let _seq_ignored = Self::read_2bits_from_buf(&buf, &mut i, packet_flags >> 1, 0)?;
481 let mut padsize = Self::read_2bits_from_buf(&buf, &mut i, packet_flags >> 3, 0)? as u32;
482
483 if packet_length == 0 || packet_length >= (1u32 << 29) {
484 return Ok(out);
485 }
486 if padsize >= packet_length {
487 return Ok(out);
488 }
489
490 if i + 6 > buf.len() {
491 return Ok(out);
492 }
493 let packet_timestamp = u32::from_le_bytes([buf[i], buf[i + 1], buf[i + 2], buf[i + 3]]);
494 i += 4;
495 let _duration = u16::from_le_bytes([buf[i], buf[i + 1]]);
496 i += 2;
497
498 let (packet_segsizetype, mut packet_segments): (u8, i32) = if (packet_flags & 0x01) != 0 {
499 if i >= buf.len() {
500 return Ok(out);
501 }
502 let st = buf[i];
503 i += 1;
504 (st, (st & 0x3f) as i32)
505 } else {
506 (0x80u8, 1)
507 };
508
509 let header_len = i as u32;
511 if header_len > packet_length.saturating_sub(padsize) {
512 return Ok(out);
513 }
514
515 let mut packet_size_left: i32 = (packet_length - padsize - header_len) as i32;
517
518 if packet_length < self.min_packet_size {
520 padsize = padsize.saturating_add(self.min_packet_size - packet_length);
521 }
522 let mut packet_padsize: i32 = padsize as i32;
523
524 let mut packet_time_start: u32 = 0;
526 let mut packet_time_delta: u8 = 0;
527 let mut packet_multi_size: i32 = 0;
528
529 let mut cur_stream_num: u8 = 0;
531 let mut packet_seq: u32 = 0;
532 let mut packet_frag_offset: u32 = 0;
533 let mut packet_replic_size: u32 = 0;
534 let mut packet_key_frame: bool = false;
535 let mut packet_frag_size: u32 = 0;
536 let mut packet_frag_timestamp: u32 = 0;
537 let mut packet_obj_size: u32 = 0;
538
539 loop {
541 if packet_size_left < FRAME_HEADER_SIZE
542 || (packet_segments < 1 && packet_time_start == 0)
543 {
544 let _ = packet_padsize;
546 break;
547 }
548
549 if packet_time_start == 0 {
550 if i >= buf.len() {
552 break;
553 }
554 let num = buf[i];
555 i += 1;
556 packet_size_left -= 1;
557
558 packet_segments -= 1;
559 packet_key_frame = (num & 0x80) != 0;
560 cur_stream_num = num & 0x7f;
561
562 let mut before = i;
564 packet_seq = Self::read_2bits_from_buf(&buf, &mut i, packet_property >> 4, 0)?;
565 packet_size_left -= (i - before) as i32;
566
567 before = i;
568 packet_frag_offset =
569 Self::read_2bits_from_buf(&buf, &mut i, packet_property >> 2, 0)?;
570 packet_size_left -= (i - before) as i32;
571
572 before = i;
573 packet_replic_size = Self::read_2bits_from_buf(&buf, &mut i, packet_property, 0)?;
574 packet_size_left -= (i - before) as i32;
575
576 if (packet_replic_size as i32) > packet_size_left {
579 break;
581 }
582
583 packet_obj_size = 0;
584
585 if packet_replic_size >= 8 {
586 if i + 8 > buf.len() {
587 break;
588 }
589 packet_obj_size =
590 u32::from_le_bytes([buf[i], buf[i + 1], buf[i + 2], buf[i + 3]]);
591 i += 4;
592 packet_frag_timestamp =
593 u32::from_le_bytes([buf[i], buf[i + 1], buf[i + 2], buf[i + 3]]);
594 i += 4;
595 packet_size_left -= 8;
596
597 let skip = (packet_replic_size - 8) as usize;
598 if i + skip > buf.len() {
599 break;
600 }
601 i += skip;
602 packet_size_left -= skip as i32;
603 } else if packet_replic_size == 1 {
604 packet_time_start = packet_frag_offset;
606 packet_frag_offset = 0;
607 packet_frag_timestamp = packet_timestamp;
608
609 if i >= buf.len() {
610 break;
611 }
612 packet_time_delta = buf[i];
613 i += 1;
614 packet_size_left -= 1;
615 } else if packet_replic_size != 0 {
616 break;
618 }
619
620 if (packet_flags & 0x01) != 0 {
622 let before = i;
623 packet_frag_size =
624 Self::read_2bits_from_buf(&buf, &mut i, packet_segsizetype >> 6, 0)?;
625 let consumed = (i - before) as i32;
626 packet_size_left -= consumed;
627
628 if packet_frag_size == 0 {
629 break;
630 }
631
632 if packet_frag_size as i32 > packet_size_left {
634 if packet_frag_size as i32 > packet_size_left + packet_padsize {
635 break;
636 }
637 let diff = packet_frag_size as i32 - packet_size_left;
638 packet_size_left += diff;
639 packet_padsize -= diff;
640 }
641 } else {
642 packet_frag_size = packet_size_left as u32;
644 }
645
646 if packet_replic_size == 1 {
647 packet_multi_size = packet_frag_size as i32;
648 if packet_multi_size > packet_size_left {
649 break;
650 }
651 }
652 }
653
654 if packet_replic_size == 1 {
656 packet_frag_timestamp = packet_time_start;
657 packet_time_start = packet_time_start.wrapping_add(packet_time_delta as u32);
658
659 if i >= buf.len() {
660 break;
661 }
662 let sz = buf[i] as u32;
663 i += 1;
664 packet_size_left -= 1;
665 packet_multi_size -= 1;
666
667 packet_obj_size = sz;
668 packet_frag_size = sz;
669 packet_frag_offset = 0;
670
671 if packet_multi_size < packet_obj_size as i32 {
672 let drop = packet_multi_size.max(0) as usize;
674 if i + drop > buf.len() {
675 break;
676 }
677 i += drop;
678 packet_size_left -= drop as i32;
679 packet_time_start = 0;
680 packet_multi_size = 0;
681 continue;
682 }
683
684 packet_multi_size -= packet_obj_size as i32;
685
686 packet_key_frame = true;
688 }
689
690 let frag_size = packet_frag_size as usize;
691 if frag_size == 0 {
692 break;
693 }
694 if packet_size_left < frag_size as i32 {
695 break;
696 }
697 if i + frag_size > buf.len() {
698 break;
699 }
700
701 let data = &buf[i..i + frag_size];
703 i += frag_size;
704 packet_size_left -= frag_size as i32;
705
706 if packet_replic_size != 1 {
708 packet_time_start = 0;
709 }
710
711 let pts_ms = packet_frag_timestamp.saturating_sub(self.preroll_ms);
712
713 if packet_obj_size == 0 {
714 out.push(AsfPayload {
716 stream_number: cur_stream_num,
717 object_id: packet_seq,
718 obj_offset: 0,
719 obj_size: data.len() as u32,
720 pts_ms,
721 duration_ms: 0,
722 is_key_frame: packet_key_frame,
723 data: data.to_vec(),
724 });
725 continue;
726 }
727
728 let st = &mut self.streams[cur_stream_num as usize];
730
731 if st.frag_offset_sum == 0 && packet_frag_offset != 0 {
732 continue;
734 }
735
736 let obj_size = packet_obj_size as usize;
737 let frag_off = packet_frag_offset as usize;
738
739 let need_new =
740 st.pkt.len() != obj_size || st.frag_offset_sum + frag_size > st.pkt.len();
741 if need_new {
742 st.pkt.clear();
743 st.pkt.resize(obj_size, 0);
744 st.frag_offset_sum = 0;
745 st.pkt_clean = false;
746 st.seq = packet_seq;
747 st.pts_ms = pts_ms;
748 st.is_key = packet_key_frame || self.is_audio_stream[cur_stream_num as usize];
749 }
750
751 if frag_off >= st.pkt.len() || frag_size > st.pkt.len().saturating_sub(frag_off) {
752 continue;
753 }
754
755 if frag_off != st.frag_offset_sum && !st.pkt_clean {
756 for b in &mut st.pkt[st.frag_offset_sum..] {
758 *b = 0;
759 }
760 st.pkt_clean = true;
761 }
762
763 st.pkt[frag_off..frag_off + frag_size].copy_from_slice(data);
764 st.frag_offset_sum += frag_size;
765
766 if st.frag_offset_sum == st.pkt.len() {
767 let seq = st.seq;
770 let pts_ms_full = st.pts_ms;
771 let is_key_full = st.is_key;
772
773 let mut full = std::mem::take(&mut st.pkt);
774 st.frag_offset_sum = 0;
775 st.pkt_clean = false;
776
777 if self.is_audio_stream[cur_stream_num as usize] {
779 full = self.descramble_audio_if_needed(cur_stream_num, full);
780 }
781
782 out.push(AsfPayload {
783 stream_number: cur_stream_num,
784 object_id: seq,
785 obj_offset: 0,
786 obj_size: full.len() as u32,
787 pts_ms: pts_ms_full,
788 duration_ms: 0,
789 is_key_frame: is_key_full,
790 data: full,
791 });
792 }
793 }
794
795 Ok(out)
796 }
797}