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