pgs_parse/
pgs_segment_header.rs

1//! # PGS Segment Header
2//!
3//! This module defines the `PgsSegmentHeader` struct, which represents the header of a PGS segment.
4
5use crate::pgs_const::PG;
6use crate::pgs_memory_buffer::{BigEndian, ReadBytes};
7use crate::pgs_segment_type::PgsSegmentType;
8use crate::pgs_error::{Result, Error};
9use crate::PgsMemoryBuffer;
10
11/// Constant defining the length of a PGS segment header.
12pub const PGS_SEGMENT_HEADER_LENGTH: usize = 13;
13
14/// Struct representing the header of a PGS segment.
15#[derive(Debug)]
16pub struct PgsSegmentHeader {
17    // The type of the segment, as defined by the PGS specification.
18    pub segment_type: PgsSegmentType,
19    /// The length of the segment (excluding the header).
20    pub segment_length: u16,
21    /// The presentation timestamp (PTS) for the segment.
22    pub presentation_timestamp: u32,
23    /// The decoding timestamp (DTS) for the segment.
24    pub decoding_timestamp: u32
25}
26
27impl PgsSegmentHeader {
28    fn new(segment_type: PgsSegmentType, presentation_timestamp: u32, decoding_timestamp: u32, segment_length: u16) -> Self {
29        PgsSegmentHeader {
30            segment_type,
31            segment_length,
32            presentation_timestamp,
33            decoding_timestamp
34        }
35    }
36
37    /// Parses a `PgsSegmentHeader` from the provided raw data.
38    ///
39    /// This function reads the necessary fields from the data buffer and constructs a `PgsSegmentHeader`.
40    /// It checks the validity of the header, ensuring that the segment begins with the expected `PG` marker.
41    ///
42    /// # Parameters
43    /// - `data`: A slice of raw data representing the contents of the PGS segment header.
44    ///
45    /// # Errors
46    /// Returns an error if the length of the data is less than the required header length or if the header is invalid.
47    ///
48    /// # Returns
49    /// A `PgsSegmentHeader` constructed from the provided data.
50    pub fn from_data(data: &[u8]) -> Result<PgsSegmentHeader> {
51        if data.len() < PGS_SEGMENT_HEADER_LENGTH {
52            return Err(Error::InvalidSegmentDataLength);
53        }
54
55        let mut buffer: PgsMemoryBuffer = PgsMemoryBuffer::from(data);
56
57        let pg = buffer.read_u16::<BigEndian>()?;
58        if pg != PG {
59            return Err(Error::ReadInvalidSegment);
60        }
61        
62        let pts = buffer.read_u32::<BigEndian>()?;
63        let dts = buffer.read_u32::<BigEndian>()?;
64        let s_type = PgsSegmentType::from(buffer.read_u8()?);
65        let s_size = buffer.read_u16::<BigEndian>()?;
66
67        Ok(PgsSegmentHeader::new(s_type, pts, dts, s_size))
68    }
69}
70
71impl Default for PgsSegmentHeader {
72    /// Provides a default implementation for the `PgsSegmentHeader`.
73    /// This default header has a segment type of `ERR` and zero for all other fields.
74    fn default() -> Self {
75        Self { segment_type: PgsSegmentType::ERR, segment_length: 0, presentation_timestamp: 0, decoding_timestamp: 0 }
76    }
77}