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}