1use bytecodec::bytes::{BytesEncoder, RemainingBytesDecoder};
2use bytecodec::combinator::{Length, Peekable};
3use bytecodec::fixnum::{U24beDecoder, U24beEncoder, U32beEncoder, U8Decoder, U8Encoder};
4use bytecodec::{ByteCount, Decode, DecodeExt, Encode, Eos, ErrorKind, Result, SizedEncode};
5
6use {
7 AacPacketType, AvcPacketType, CodecId, FrameType, SoundFormat, SoundRate, SoundSize, SoundType,
8 StreamId, TimeOffset, Timestamp,
9};
10
11const TAG_TYPE_AUDIO: u8 = 8;
12const TAG_TYPE_VIDEO: u8 = 9;
13const TAG_TYPE_SCRIPT_DATA: u8 = 18;
14
15#[derive(Debug, Clone)]
17pub enum Tag<Data = Vec<u8>> {
18 Audio(AudioTag<Data>),
20
21 Video(VideoTag<Data>),
23
24 ScriptData(ScriptDataTag<Data>),
26}
27impl<Data> Tag<Data> {
28 pub fn kind(&self) -> TagKind {
30 match self {
31 Tag::Audio(_) => TagKind::Audio,
32 Tag::Video(_) => TagKind::Video,
33 Tag::ScriptData(_) => TagKind::ScriptData,
34 }
35 }
36
37 pub fn timestamp(&self) -> Timestamp {
39 match self {
40 Tag::Audio(t) => t.timestamp,
41 Tag::Video(t) => t.timestamp,
42 Tag::ScriptData(t) => t.timestamp,
43 }
44 }
45
46 pub fn stream_id(&self) -> StreamId {
48 match self {
49 Tag::Audio(t) => t.stream_id,
50 Tag::Video(t) => t.stream_id,
51 Tag::ScriptData(t) => t.stream_id,
52 }
53 }
54}
55impl<Data: AsRef<[u8]>> Tag<Data> {
56 pub fn tag_size(&self) -> u32 {
58 match self {
59 Tag::Audio(t) => t.tag_size(),
60 Tag::Video(t) => t.tag_size(),
61 Tag::ScriptData(t) => t.tag_size(),
62 }
63 }
64}
65impl<Data> From<AudioTag<Data>> for Tag<Data> {
66 fn from(f: AudioTag<Data>) -> Self {
67 Tag::Audio(f)
68 }
69}
70impl<Data> From<VideoTag<Data>> for Tag<Data> {
71 fn from(f: VideoTag<Data>) -> Self {
72 Tag::Video(f)
73 }
74}
75impl<Data> From<ScriptDataTag<Data>> for Tag<Data> {
76 fn from(f: ScriptDataTag<Data>) -> Self {
77 Tag::ScriptData(f)
78 }
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
83#[allow(missing_docs)]
84pub enum TagKind {
85 Audio = TAG_TYPE_AUDIO as isize,
86 Video = TAG_TYPE_VIDEO as isize,
87 ScriptData = TAG_TYPE_SCRIPT_DATA as isize,
88}
89
90#[derive(Debug, Clone)]
92pub struct AudioTag<Data = Vec<u8>> {
93 pub timestamp: Timestamp,
95
96 pub stream_id: StreamId,
98
99 pub sound_format: SoundFormat,
101
102 pub sound_rate: SoundRate,
104
105 pub sound_size: SoundSize,
107
108 pub sound_type: SoundType,
110
111 pub aac_packet_type: Option<AacPacketType>,
115
116 pub data: Data,
118}
119impl<Data: AsRef<[u8]>> AudioTag<Data> {
120 pub fn tag_size(&self) -> u32 {
122 let mut size = TagHeader::SIZE + 1 + self.data.as_ref().len() as u32;
123 if self.aac_packet_type.is_some() {
124 size += 1;
125 }
126 size
127 }
128}
129
130#[derive(Debug, Clone)]
132pub struct VideoTag<Data = Vec<u8>> {
133 pub timestamp: Timestamp,
135
136 pub stream_id: StreamId,
138
139 pub frame_type: FrameType,
141
142 pub codec_id: CodecId,
144
145 pub avc_packet_type: Option<AvcPacketType>,
150
151 pub composition_time: Option<TimeOffset>,
156
157 pub data: Data,
159}
160impl<Data: AsRef<[u8]>> VideoTag<Data> {
161 pub fn tag_size(&self) -> u32 {
163 let mut size = TagHeader::SIZE + 1 + self.data.as_ref().len() as u32;
164 if self.avc_packet_type.is_some() {
165 size += 4;
166 }
167 size
168 }
169}
170
171#[derive(Debug, Clone)]
173pub struct ScriptDataTag<Data = Vec<u8>> {
174 pub timestamp: Timestamp,
176
177 pub stream_id: StreamId,
179
180 pub data: Data,
184}
185impl<Data: AsRef<[u8]>> ScriptDataTag<Data> {
186 pub fn tag_size(&self) -> u32 {
188 TagHeader::SIZE + self.data.as_ref().len() as u32
189 }
190}
191
192#[derive(Debug, Default)]
194pub struct TagDecoder {
195 header: Peekable<TagHeaderDecoder>,
196 data: Length<TagDataDecoder>,
197}
198impl TagDecoder {
199 pub fn new() -> Self {
201 TagDecoder::default()
202 }
203}
204impl Decode for TagDecoder {
205 type Item = Tag;
206
207 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
208 let mut offset = 0;
209 if !self.header.is_idle() {
210 bytecodec_try_decode!(self.header, offset, buf, eos);
211 let header = self.header.peek().expect("Never fails");
212 let data = match header.tag_type {
213 TagKind::Audio => TagDataDecoder::Audio(Default::default()),
214 TagKind::Video => TagDataDecoder::Video(Default::default()),
215 TagKind::ScriptData => TagDataDecoder::ScriptData(Default::default()),
216 };
217 self.data = data.length(u64::from(header.data_size));
218 }
219 bytecodec_try_decode!(self.data, offset, buf, eos);
220 Ok(offset)
221 }
222
223 fn finish_decoding(&mut self) -> Result<Self::Item> {
224 let header = track!(self.header.finish_decoding())?;
225 let data = track!(self.data.finish_decoding())?;
226 let tag = match data {
227 TagData::Audio(d) => Tag::from(AudioTag {
228 timestamp: header.timestamp,
229 stream_id: header.stream_id,
230 sound_format: d.sound_format,
231 sound_rate: d.sound_rate,
232 sound_size: d.sound_size,
233 sound_type: d.sound_type,
234 aac_packet_type: d.aac_packet_type,
235 data: d.data,
236 }),
237 TagData::Video(d) => Tag::from(VideoTag {
238 timestamp: header.timestamp,
239 stream_id: header.stream_id,
240 frame_type: d.frame_type,
241 codec_id: d.codec_id,
242 avc_packet_type: d.avc_packet_type,
243 composition_time: d.composition_time,
244 data: d.data,
245 }),
246 TagData::ScriptData(d) => Tag::from(ScriptDataTag {
247 timestamp: header.timestamp,
248 stream_id: header.stream_id,
249 data: d.data,
250 }),
251 };
252 Ok(tag)
253 }
254
255 fn is_idle(&self) -> bool {
256 self.header.is_idle() && self.data.is_idle()
257 }
258
259 fn requiring_bytes(&self) -> ByteCount {
260 if self.header.is_idle() {
261 self.data.requiring_bytes()
262 } else {
263 self.header.requiring_bytes()
264 }
265 }
266}
267
268#[derive(Debug)]
269struct TagHeader {
270 tag_type: TagKind,
271 data_size: u32, timestamp: Timestamp,
273 stream_id: StreamId,
274}
275impl TagHeader {
276 const SIZE: u32 = 11;
277}
278
279#[derive(Debug, Default)]
280struct TagHeaderDecoder {
281 tag_type: U8Decoder,
282 data_size: U24beDecoder,
283 timestamp: U24beDecoder,
284 timestamp_extended: U8Decoder,
285 stream_id: U24beDecoder,
286}
287impl Decode for TagHeaderDecoder {
288 type Item = TagHeader;
289
290 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
291 let mut offset = 0;
292 bytecodec_try_decode!(self.tag_type, offset, buf, eos);
293 bytecodec_try_decode!(self.data_size, offset, buf, eos);
294 bytecodec_try_decode!(self.timestamp, offset, buf, eos);
295 bytecodec_try_decode!(self.timestamp_extended, offset, buf, eos);
296 bytecodec_try_decode!(self.stream_id, offset, buf, eos);
297 Ok(offset)
298 }
299
300 fn finish_decoding(&mut self) -> Result<Self::Item> {
301 let tag_type = track!(self.tag_type.finish_decoding())?;
302 let data_size = track!(self.data_size.finish_decoding())?;
303 let timestamp = track!(self.timestamp.finish_decoding())?;
304 let timestamp_extended = track!(self.timestamp_extended.finish_decoding())?;
305 let stream_id = track!(self.stream_id.finish_decoding())?;
306
307 let tag_type = match tag_type {
308 TAG_TYPE_AUDIO => TagKind::Audio,
309 TAG_TYPE_VIDEO => TagKind::Video,
310 TAG_TYPE_SCRIPT_DATA => TagKind::ScriptData,
311 _ => track_panic!(
312 ErrorKind::InvalidInput,
313 "Unknown FLV tag type: {}",
314 tag_type
315 ),
316 };
317 track_assert!(
318 data_size <= 0x00FF_FFFF,
319 ErrorKind::InvalidInput,
320 "Too large FLV tag data size: {}",
321 data_size
322 );
323 let timestamp = Timestamp::new((timestamp as i32) | i32::from(timestamp_extended) << 24);
324 Ok(TagHeader {
325 tag_type,
326 data_size,
327 timestamp,
328 stream_id: track!(StreamId::new(stream_id))?,
329 })
330 }
331
332 fn is_idle(&self) -> bool {
333 self.stream_id.is_idle()
334 }
335
336 fn requiring_bytes(&self) -> ByteCount {
337 self.tag_type
338 .requiring_bytes()
339 .add_for_decoding(self.data_size.requiring_bytes())
340 .add_for_decoding(self.timestamp.requiring_bytes())
341 .add_for_decoding(self.timestamp_extended.requiring_bytes())
342 .add_for_decoding(self.stream_id.requiring_bytes())
343 }
344}
345
346#[derive(Debug)]
347enum TagData {
348 Audio(AudioTagData),
349 Video(VideoTagData),
350 ScriptData(ScriptDataTagData),
351}
352
353#[derive(Debug)]
354struct AudioTagData {
355 pub sound_format: SoundFormat,
356 pub sound_rate: SoundRate,
357 pub sound_size: SoundSize,
358 pub sound_type: SoundType,
359 pub aac_packet_type: Option<AacPacketType>,
360 pub data: Vec<u8>,
361}
362
363#[derive(Debug)]
364struct VideoTagData {
365 frame_type: FrameType,
366 codec_id: CodecId,
367 avc_packet_type: Option<AvcPacketType>,
368 composition_time: Option<TimeOffset>,
369 data: Vec<u8>,
370}
371
372#[derive(Debug)]
373struct ScriptDataTagData {
374 data: Vec<u8>,
375}
376
377#[derive(Debug)]
378enum TagDataDecoder {
379 Audio(AudioTagDataDecoder),
380 Video(VideoTagDataDecoder),
381 ScriptData(ScriptDataTagDataDecoder),
382 None,
383}
384impl Decode for TagDataDecoder {
385 type Item = TagData;
386
387 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
388 match self {
389 TagDataDecoder::Audio(d) => track!(d.decode(buf, eos)),
390 TagDataDecoder::Video(d) => track!(d.decode(buf, eos)),
391 TagDataDecoder::ScriptData(d) => track!(d.decode(buf, eos)),
392 TagDataDecoder::None => track_panic!(ErrorKind::InconsistentState),
393 }
394 }
395
396 fn finish_decoding(&mut self) -> Result<Self::Item> {
397 let data = match self {
398 TagDataDecoder::Audio(d) => TagData::Audio(track!(d.finish_decoding())?),
399 TagDataDecoder::Video(d) => TagData::Video(track!(d.finish_decoding())?),
400 TagDataDecoder::ScriptData(d) => TagData::ScriptData(track!(d.finish_decoding())?),
401 TagDataDecoder::None => track_panic!(ErrorKind::InconsistentState),
402 };
403 *self = TagDataDecoder::None;
404 Ok(data)
405 }
406
407 fn is_idle(&self) -> bool {
408 match self {
409 TagDataDecoder::Audio(d) => d.is_idle(),
410 TagDataDecoder::Video(d) => d.is_idle(),
411 TagDataDecoder::ScriptData(d) => d.is_idle(),
412 TagDataDecoder::None => true,
413 }
414 }
415
416 fn requiring_bytes(&self) -> ByteCount {
417 match self {
418 TagDataDecoder::Audio(d) => d.requiring_bytes(),
419 TagDataDecoder::Video(d) => d.requiring_bytes(),
420 TagDataDecoder::ScriptData(d) => d.requiring_bytes(),
421 TagDataDecoder::None => ByteCount::Finite(0),
422 }
423 }
424}
425impl Default for TagDataDecoder {
426 fn default() -> Self {
427 TagDataDecoder::None
428 }
429}
430
431#[derive(Debug, Default)]
432struct AudioTagDataDecoder {
433 header: Peekable<U8Decoder>,
434 aac_packet_type: U8Decoder,
435 data: RemainingBytesDecoder,
436}
437impl AudioTagDataDecoder {
438 fn is_aac_packet(&self) -> bool {
439 self.header.peek().map_or(false, |&b| (b >> 4) == 10)
440 }
441}
442impl Decode for AudioTagDataDecoder {
443 type Item = AudioTagData;
444
445 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
446 let mut offset = 0;
447 bytecodec_try_decode!(self.header, offset, buf, eos);
448 if self.is_aac_packet() {
449 bytecodec_try_decode!(self.aac_packet_type, offset, buf, eos);
450 }
451 bytecodec_try_decode!(self.data, offset, buf, eos);
452 Ok(offset)
453 }
454
455 fn finish_decoding(&mut self) -> Result<Self::Item> {
456 let b = track!(self.header.finish_decoding())?;
457 let sound_format = track!(SoundFormat::from_u8(b >> 4))?;
458 let sound_rate = track!(SoundRate::from_u8((b >> 2) & 0b11))?;
459 let sound_size = SoundSize::from_bool((b & 0b10) != 0);
460 let sound_type = SoundType::from_bool((b & 0b01) != 0);
461
462 let aac_packet_type = if let SoundFormat::Aac = sound_format {
463 let b = track!(self.aac_packet_type.finish_decoding())?;
464 Some(track!(AacPacketType::from_u8(b))?)
465 } else {
466 None
467 };
468
469 let data = track!(self.data.finish_decoding())?;
470 Ok(AudioTagData {
471 sound_format,
472 sound_rate,
473 sound_size,
474 sound_type,
475 aac_packet_type,
476 data,
477 })
478 }
479
480 fn is_idle(&self) -> bool {
481 self.data.is_idle()
482 }
483
484 fn requiring_bytes(&self) -> ByteCount {
485 ByteCount::Unknown
486 }
487}
488
489#[derive(Debug, Default)]
490struct FrameTypeAndCodecDecoder(U8Decoder);
491impl Decode for FrameTypeAndCodecDecoder {
492 type Item = (FrameType, CodecId);
493
494 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
495 track!(self.0.decode(buf, eos))
496 }
497
498 fn finish_decoding(&mut self) -> Result<Self::Item> {
499 let b = track!(self.0.finish_decoding())?;
500 let frame_type = track!(FrameType::from_u8(b >> 4))?;
501 let codec_id = track!(CodecId::from_u8(b & 0b1111))?;
502 Ok((frame_type, codec_id))
503 }
504
505 fn is_idle(&self) -> bool {
506 self.0.is_idle()
507 }
508
509 fn requiring_bytes(&self) -> ByteCount {
510 self.0.requiring_bytes()
511 }
512}
513
514#[derive(Debug, Default)]
515struct VideoTagDataDecoder {
516 frame_type_and_codec: Peekable<FrameTypeAndCodecDecoder>,
517 avc_packet_type: U8Decoder,
518 composition_time: U24beDecoder,
519 data: RemainingBytesDecoder,
520}
521impl VideoTagDataDecoder {
522 fn is_avc_packet(&self) -> bool {
523 self.frame_type_and_codec.peek().map_or(false, |t| {
524 t.0 != FrameType::VideoInfoOrCommandFrame && t.1 == CodecId::Avc
525 })
526 }
527}
528impl Decode for VideoTagDataDecoder {
529 type Item = VideoTagData;
530
531 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
532 let mut offset = 0;
533 bytecodec_try_decode!(self.frame_type_and_codec, offset, buf, eos);
534 if self.is_avc_packet() {
535 bytecodec_try_decode!(self.avc_packet_type, offset, buf, eos);
536 bytecodec_try_decode!(self.composition_time, offset, buf, eos);
537 }
538 bytecodec_try_decode!(self.data, offset, buf, eos);
539 Ok(offset)
540 }
541
542 fn finish_decoding(&mut self) -> Result<Self::Item> {
543 let is_avc_packet = self.is_avc_packet();
544
545 let (frame_type, codec_id) = track!(self.frame_type_and_codec.finish_decoding())?;
546 let avc_packet_type = if is_avc_packet {
547 let avc_packet_type = track!(self.avc_packet_type.finish_decoding())?;
548 let avc_packet_type = track!(AvcPacketType::from_u8(avc_packet_type))?;
549 Some(avc_packet_type)
550 } else {
551 None
552 };
553 let composition_time = if is_avc_packet {
554 let composition_time = track!(self.composition_time.finish_decoding())?;
555 let composition_time = TimeOffset::from_u24(composition_time);
556 Some(composition_time)
557 } else {
558 None
559 };
560 let data = track!(self.data.finish_decoding())?;
561 Ok(VideoTagData {
562 frame_type,
563 codec_id,
564 avc_packet_type,
565 composition_time,
566 data,
567 })
568 }
569
570 fn is_idle(&self) -> bool {
571 self.data.is_idle()
572 }
573
574 fn requiring_bytes(&self) -> ByteCount {
575 ByteCount::Unknown
576 }
577}
578
579#[derive(Debug, Default)]
580struct ScriptDataTagDataDecoder(RemainingBytesDecoder);
581impl Decode for ScriptDataTagDataDecoder {
582 type Item = ScriptDataTagData;
583
584 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
585 track!(self.0.decode(buf, eos))
586 }
587
588 fn finish_decoding(&mut self) -> Result<Self::Item> {
589 let data = track!(self.0.finish_decoding())?;
590 Ok(ScriptDataTagData { data })
591 }
592
593 fn is_idle(&self) -> bool {
594 self.0.is_idle()
595 }
596
597 fn requiring_bytes(&self) -> ByteCount {
598 self.0.requiring_bytes()
599 }
600}
601
602#[derive(Debug)]
604pub struct TagEncoder<Data> {
605 audio: AudioTagEncoder<Data>,
606 video: VideoTagEncoder<Data>,
607 script_data: ScriptDataTagEncoder<Data>,
608}
609impl<Data> TagEncoder<Data> {
610 pub fn new() -> Self {
612 Self::default()
613 }
614}
615impl<Data: AsRef<[u8]>> Encode for TagEncoder<Data> {
616 type Item = Tag<Data>;
617
618 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
619 let mut offset = 0;
620 bytecodec_try_encode!(self.audio, offset, buf, eos);
621 bytecodec_try_encode!(self.video, offset, buf, eos);
622 bytecodec_try_encode!(self.script_data, offset, buf, eos);
623 Ok(offset)
624 }
625
626 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
627 match item {
628 Tag::Audio(t) => track!(self.audio.start_encoding(t)),
629 Tag::Video(t) => track!(self.video.start_encoding(t)),
630 Tag::ScriptData(t) => track!(self.script_data.start_encoding(t)),
631 }
632 }
633
634 fn requiring_bytes(&self) -> ByteCount {
635 ByteCount::Finite(self.exact_requiring_bytes())
636 }
637
638 fn is_idle(&self) -> bool {
639 self.audio.is_idle() && self.video.is_idle() && self.script_data.is_idle()
640 }
641}
642impl<Data: AsRef<[u8]>> SizedEncode for TagEncoder<Data> {
643 fn exact_requiring_bytes(&self) -> u64 {
644 self.audio.exact_requiring_bytes()
645 + self.video.exact_requiring_bytes()
646 + self.script_data.exact_requiring_bytes()
647 }
648}
649impl<Data> Default for TagEncoder<Data> {
650 fn default() -> Self {
651 TagEncoder {
652 audio: AudioTagEncoder::default(),
653 video: VideoTagEncoder::default(),
654 script_data: ScriptDataTagEncoder::default(),
655 }
656 }
657}
658
659#[derive(Debug)]
660struct AudioTagEncoder<Data> {
661 header: TagHeaderEncoder,
662 audio_specific: U8Encoder,
663 aac_specific: U8Encoder,
664 data: BytesEncoder<Data>,
665}
666impl<Data: AsRef<[u8]>> Encode for AudioTagEncoder<Data> {
667 type Item = AudioTag<Data>;
668
669 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
670 let mut offset = 0;
671 bytecodec_try_encode!(self.header, offset, buf, eos);
672 bytecodec_try_encode!(self.audio_specific, offset, buf, eos);
673 bytecodec_try_encode!(self.aac_specific, offset, buf, eos);
674 bytecodec_try_encode!(self.data, offset, buf, eos);
675 Ok(offset)
676 }
677
678 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
679 let audio_specific = ((item.sound_format as u8) << 4)
680 | ((item.sound_rate as u8) << 2)
681 | ((item.sound_size as u8) << 1)
682 | (item.sound_type as u8);
683 track!(self.audio_specific.start_encoding(audio_specific))?;
684 if let Some(packet_type) = item.aac_packet_type {
685 track!(self.aac_specific.start_encoding(packet_type as u8))?;
686 }
687 track!(self.data.start_encoding(item.data))?;
688 let data_size = self.audio_specific.exact_requiring_bytes()
689 + self.aac_specific.exact_requiring_bytes()
690 + self.data.exact_requiring_bytes();
691 track_assert!(data_size <= 0xFF_FFFF, ErrorKind::InvalidInput; data_size);
692
693 let header = TagHeader {
694 tag_type: TagKind::Audio,
695 data_size: data_size as u32,
696 timestamp: item.timestamp,
697 stream_id: item.stream_id,
698 };
699 track!(self.header.start_encoding(header))?;
700 Ok(())
701 }
702
703 fn requiring_bytes(&self) -> ByteCount {
704 ByteCount::Finite(self.exact_requiring_bytes())
705 }
706
707 fn is_idle(&self) -> bool {
708 self.header.is_idle()
709 && self.audio_specific.is_idle()
710 && self.aac_specific.is_idle()
711 && self.data.is_idle()
712 }
713}
714impl<Data: AsRef<[u8]>> SizedEncode for AudioTagEncoder<Data> {
715 fn exact_requiring_bytes(&self) -> u64 {
716 self.header.exact_requiring_bytes()
717 + self.audio_specific.exact_requiring_bytes()
718 + self.aac_specific.exact_requiring_bytes()
719 + self.data.exact_requiring_bytes()
720 }
721}
722impl<Data> Default for AudioTagEncoder<Data> {
723 fn default() -> Self {
724 AudioTagEncoder {
725 header: TagHeaderEncoder::default(),
726 audio_specific: U8Encoder::default(),
727 aac_specific: U8Encoder::default(),
728 data: BytesEncoder::default(),
729 }
730 }
731}
732
733#[derive(Debug)]
734struct VideoTagEncoder<Data> {
735 header: TagHeaderEncoder,
736 video_specific: U8Encoder,
737 avc_specific: U32beEncoder,
738 data: BytesEncoder<Data>,
739}
740impl<Data: AsRef<[u8]>> Encode for VideoTagEncoder<Data> {
741 type Item = VideoTag<Data>;
742
743 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
744 let mut offset = 0;
745 bytecodec_try_encode!(self.header, offset, buf, eos);
746 bytecodec_try_encode!(self.video_specific, offset, buf, eos);
747 bytecodec_try_encode!(self.avc_specific, offset, buf, eos);
748 bytecodec_try_encode!(self.data, offset, buf, eos);
749 Ok(offset)
750 }
751
752 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
753 let video_specific = ((item.frame_type as u8) << 4) | (item.codec_id as u8);
754 track!(self.video_specific.start_encoding(video_specific))?;
755 if let Some(packet_type) = item.avc_packet_type {
756 let ct = track_assert_some!(item.composition_time, ErrorKind::InvalidInput);
757 let avc_specific = ((packet_type as u32) << 24) | ((ct.value() as u32) & 0xFF_FFFF);
758 track!(self.avc_specific.start_encoding(avc_specific))?;
759 }
760 track!(self.data.start_encoding(item.data))?;
761 let data_size = self.video_specific.exact_requiring_bytes()
762 + self.avc_specific.exact_requiring_bytes()
763 + self.data.exact_requiring_bytes();
764 track_assert!(data_size <= 0xFF_FFFF, ErrorKind::InvalidInput; data_size);
765
766 let header = TagHeader {
767 tag_type: TagKind::Video,
768 data_size: data_size as u32,
769 timestamp: item.timestamp,
770 stream_id: item.stream_id,
771 };
772 track!(self.header.start_encoding(header))?;
773 Ok(())
774 }
775
776 fn requiring_bytes(&self) -> ByteCount {
777 ByteCount::Finite(self.exact_requiring_bytes())
778 }
779
780 fn is_idle(&self) -> bool {
781 self.header.is_idle()
782 && self.video_specific.is_idle()
783 && self.avc_specific.is_idle()
784 && self.data.is_idle()
785 }
786}
787impl<Data: AsRef<[u8]>> SizedEncode for VideoTagEncoder<Data> {
788 fn exact_requiring_bytes(&self) -> u64 {
789 self.header.exact_requiring_bytes()
790 + self.video_specific.exact_requiring_bytes()
791 + self.avc_specific.exact_requiring_bytes()
792 + self.data.exact_requiring_bytes()
793 }
794}
795impl<Data> Default for VideoTagEncoder<Data> {
796 fn default() -> Self {
797 VideoTagEncoder {
798 header: TagHeaderEncoder::default(),
799 video_specific: U8Encoder::default(),
800 avc_specific: U32beEncoder::default(),
801 data: BytesEncoder::default(),
802 }
803 }
804}
805
806#[derive(Debug)]
807struct ScriptDataTagEncoder<Data> {
808 header: TagHeaderEncoder,
809 data: BytesEncoder<Data>,
810}
811impl<Data: AsRef<[u8]>> Encode for ScriptDataTagEncoder<Data> {
812 type Item = ScriptDataTag<Data>;
813
814 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
815 let mut offset = 0;
816 bytecodec_try_encode!(self.header, offset, buf, eos);
817 bytecodec_try_encode!(self.data, offset, buf, eos);
818 Ok(offset)
819 }
820
821 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
822 track!(self.data.start_encoding(item.data))?;
823 let data_size = self.data.exact_requiring_bytes();
824 track_assert!(data_size <= 0xFF_FFFF, ErrorKind::InvalidInput; data_size);
825
826 let header = TagHeader {
827 tag_type: TagKind::ScriptData,
828 data_size: data_size as u32,
829 timestamp: item.timestamp,
830 stream_id: item.stream_id,
831 };
832 track!(self.header.start_encoding(header))?;
833 Ok(())
834 }
835
836 fn requiring_bytes(&self) -> ByteCount {
837 ByteCount::Finite(self.exact_requiring_bytes())
838 }
839
840 fn is_idle(&self) -> bool {
841 self.header.is_idle() && self.data.is_idle()
842 }
843}
844impl<Data: AsRef<[u8]>> SizedEncode for ScriptDataTagEncoder<Data> {
845 fn exact_requiring_bytes(&self) -> u64 {
846 self.header.exact_requiring_bytes() + self.data.exact_requiring_bytes()
847 }
848}
849impl<Data> Default for ScriptDataTagEncoder<Data> {
850 fn default() -> Self {
851 ScriptDataTagEncoder {
852 header: TagHeaderEncoder::default(),
853 data: BytesEncoder::default(),
854 }
855 }
856}
857
858#[derive(Debug, Default)]
859struct TagHeaderEncoder {
860 tag_type: U8Encoder,
861 data_size: U24beEncoder,
862 timestamp: U24beEncoder,
863 timestamp_extended: U8Encoder,
864 stream_id: U24beEncoder,
865}
866impl Encode for TagHeaderEncoder {
867 type Item = TagHeader;
868
869 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
870 let mut offset = 0;
871 bytecodec_try_encode!(self.tag_type, offset, buf, eos);
872 bytecodec_try_encode!(self.data_size, offset, buf, eos);
873 bytecodec_try_encode!(self.timestamp, offset, buf, eos);
874 bytecodec_try_encode!(self.timestamp_extended, offset, buf, eos);
875 bytecodec_try_encode!(self.stream_id, offset, buf, eos);
876 Ok(offset)
877 }
878
879 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
880 let timestamp = item.timestamp.value() as u32;
881 track!(self.tag_type.start_encoding(item.tag_type as u8))?;
882 track!(self.data_size.start_encoding(item.data_size))?;
883 track!(self.timestamp.start_encoding(timestamp & 0xFF_FFFF))?;
884 track!(
885 self.timestamp_extended
886 .start_encoding((timestamp >> 24) as u8)
887 )?;
888 track!(self.stream_id.start_encoding(item.stream_id.value()))?;
889 Ok(())
890 }
891
892 fn requiring_bytes(&self) -> ByteCount {
893 ByteCount::Finite(self.exact_requiring_bytes())
894 }
895
896 fn is_idle(&self) -> bool {
897 self.tag_type.is_idle()
898 && self.data_size.is_idle()
899 && self.timestamp.is_idle()
900 && self.timestamp_extended.is_idle()
901 && self.stream_id.is_idle()
902 }
903}
904impl SizedEncode for TagHeaderEncoder {
905 fn exact_requiring_bytes(&self) -> u64 {
906 self.tag_type.exact_requiring_bytes()
907 + self.data_size.exact_requiring_bytes()
908 + self.timestamp.exact_requiring_bytes()
909 + self.timestamp_extended.exact_requiring_bytes()
910 + self.stream_id.exact_requiring_bytes()
911 }
912}