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