scuffle_flv/video/body/legacy.rs
1//! Legacy video tag body
2//!
3//! Types and functions defined by the legacy FLV spec, Annex E.4.3.1.
4
5use std::io;
6
7use bytes::Bytes;
8use scuffle_bytes_util::BytesCursorExt;
9use scuffle_h264::AVCDecoderConfigurationRecord;
10
11use crate::video::header::legacy::{LegacyVideoTagHeader, LegacyVideoTagHeaderAvcPacket};
12
13/// Legacy FLV `VideoTagBody`
14///
15/// This is a container for video data.
16/// This enum contains the data for the different types of video tags.
17///
18/// Defined by:
19/// - video_file_format_spec_v10.pdf (Chapter 1 - The FLV File Format - Video
20/// tags)
21/// - video_file_format_spec_v10_1.pdf (Annex E.4.3.1 - VIDEODATA)
22#[derive(Debug, Clone, PartialEq)]
23pub enum LegacyVideoTagBody {
24 /// Empty body because the header contains a [`VideoCommand`](crate::video::header::VideoCommand)
25 Command,
26 /// AVC/H.264 configuration record
27 AvcVideoPacketSeqHdr(AVCDecoderConfigurationRecord),
28 /// Any other video data
29 Other {
30 /// The video data
31 data: Bytes,
32 },
33}
34
35impl LegacyVideoTagBody {
36 /// Demux the video tag body from the given reader.
37 ///
38 /// The reader will be consumed entirely.
39 pub fn demux(header: &LegacyVideoTagHeader, reader: &mut io::Cursor<Bytes>) -> io::Result<Self> {
40 match header {
41 LegacyVideoTagHeader::VideoCommand(_) => Ok(Self::Command),
42 LegacyVideoTagHeader::AvcPacket(LegacyVideoTagHeaderAvcPacket::SequenceHeader) => {
43 // AVCVIDEOPACKET
44 let avc_decoder_configuration_record = AVCDecoderConfigurationRecord::parse(reader)?;
45 Ok(Self::AvcVideoPacketSeqHdr(avc_decoder_configuration_record))
46 }
47 _ => Ok(Self::Other {
48 data: reader.extract_remaining(),
49 }),
50 }
51 }
52}