use std::vec::Vec;
#[derive(Clone, Debug, Default)]
pub struct VideoPacketExtra {
stream_index: i32,
byte_pos: Option<i64>,
side_data: Vec<SideDataEntry>,
}
impl VideoPacketExtra {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(stream_index: i32) -> Self {
Self {
stream_index,
byte_pos: None,
side_data: Vec::new(),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stream_index(&self) -> i32 {
self.stream_index
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn byte_pos(&self) -> Option<i64> {
self.byte_pos
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn side_data(&self) -> &[SideDataEntry] {
self.side_data.as_slice()
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_stream_index(mut self, value: i32) -> Self {
self.stream_index = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
self.byte_pos = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
self.side_data = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
self.stream_index = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
self.byte_pos = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
self.side_data = value;
self
}
}
#[derive(Clone, Debug, Default)]
pub struct VideoFrameExtra {
sample_aspect_ratio: Option<(u32, u32)>,
picture_type: PictureType,
key_frame: bool,
interlaced: bool,
top_field_first: bool,
best_effort_timestamp: Option<i64>,
mastering_display: Option<MasteringDisplay>,
content_light_level: Option<ContentLightLevel>,
smpte_timecode: Vec<u32>,
side_data: Vec<SideDataEntry>,
}
impl VideoFrameExtra {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new() -> Self {
Self {
sample_aspect_ratio: None,
picture_type: PictureType::Unspecified,
key_frame: false,
interlaced: false,
top_field_first: false,
best_effort_timestamp: None,
mastering_display: None,
content_light_level: None,
smpte_timecode: Vec::new(),
side_data: Vec::new(),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn sample_aspect_ratio(&self) -> Option<(u32, u32)> {
self.sample_aspect_ratio
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn picture_type(&self) -> PictureType {
self.picture_type
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn key_frame(&self) -> bool {
self.key_frame
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn interlaced(&self) -> bool {
self.interlaced
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn top_field_first(&self) -> bool {
self.top_field_first
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn best_effort_timestamp(&self) -> Option<i64> {
self.best_effort_timestamp
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn mastering_display(&self) -> Option<MasteringDisplay> {
self.mastering_display
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn content_light_level(&self) -> Option<ContentLightLevel> {
self.content_light_level
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn smpte_timecode(&self) -> &[u32] {
self.smpte_timecode.as_slice()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn side_data(&self) -> &[SideDataEntry] {
self.side_data.as_slice()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_sample_aspect_ratio(mut self, value: Option<(u32, u32)>) -> Self {
self.sample_aspect_ratio = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_picture_type(mut self, value: PictureType) -> Self {
self.picture_type = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_key_frame(mut self, value: bool) -> Self {
self.key_frame = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_interlaced(mut self, value: bool) -> Self {
self.interlaced = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_top_field_first(mut self, value: bool) -> Self {
self.top_field_first = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_best_effort_timestamp(mut self, value: Option<i64>) -> Self {
self.best_effort_timestamp = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_mastering_display(mut self, value: Option<MasteringDisplay>) -> Self {
self.mastering_display = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_content_light_level(mut self, value: Option<ContentLightLevel>) -> Self {
self.content_light_level = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub fn with_smpte_timecode(mut self, value: Vec<u32>) -> Self {
self.smpte_timecode = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
self.side_data = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_sample_aspect_ratio(&mut self, value: Option<(u32, u32)>) -> &mut Self {
self.sample_aspect_ratio = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_picture_type(&mut self, value: PictureType) -> &mut Self {
self.picture_type = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_key_frame(&mut self, value: bool) -> &mut Self {
self.key_frame = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_interlaced(&mut self, value: bool) -> &mut Self {
self.interlaced = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_top_field_first(&mut self, value: bool) -> &mut Self {
self.top_field_first = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_best_effort_timestamp(&mut self, value: Option<i64>) -> &mut Self {
self.best_effort_timestamp = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_mastering_display(&mut self, value: Option<MasteringDisplay>) -> &mut Self {
self.mastering_display = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_content_light_level(&mut self, value: Option<ContentLightLevel>) -> &mut Self {
self.content_light_level = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_smpte_timecode(&mut self, value: Vec<u32>) -> &mut Self {
self.smpte_timecode = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
self.side_data = value;
self
}
}
#[derive(Clone, Debug, Default)]
pub struct AudioPacketExtra {
stream_index: i32,
byte_pos: Option<i64>,
side_data: Vec<SideDataEntry>,
}
impl AudioPacketExtra {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(stream_index: i32) -> Self {
Self {
stream_index,
byte_pos: None,
side_data: Vec::new(),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stream_index(&self) -> i32 {
self.stream_index
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn byte_pos(&self) -> Option<i64> {
self.byte_pos
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn side_data(&self) -> &[SideDataEntry] {
self.side_data.as_slice()
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_stream_index(mut self, value: i32) -> Self {
self.stream_index = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
self.byte_pos = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
self.side_data = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
self.stream_index = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
self.byte_pos = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
self.side_data = value;
self
}
}
#[derive(Clone, Debug, Default)]
pub struct AudioFrameExtra {
best_effort_timestamp: Option<i64>,
side_data: Vec<SideDataEntry>,
}
impl AudioFrameExtra {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new() -> Self {
Self {
best_effort_timestamp: None,
side_data: Vec::new(),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn best_effort_timestamp(&self) -> Option<i64> {
self.best_effort_timestamp
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn side_data(&self) -> &[SideDataEntry] {
self.side_data.as_slice()
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_best_effort_timestamp(mut self, value: Option<i64>) -> Self {
self.best_effort_timestamp = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
self.side_data = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_best_effort_timestamp(&mut self, value: Option<i64>) -> &mut Self {
self.best_effort_timestamp = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
self.side_data = value;
self
}
}
#[derive(Clone, Debug, Default)]
pub struct SubtitlePacketExtra {
stream_index: i32,
language: Option<[u8; 3]>,
forced: bool,
}
impl SubtitlePacketExtra {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(stream_index: i32) -> Self {
Self {
stream_index,
language: None,
forced: false,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stream_index(&self) -> i32 {
self.stream_index
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn language(&self) -> Option<[u8; 3]> {
self.language
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn forced(&self) -> bool {
self.forced
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_stream_index(mut self, value: i32) -> Self {
self.stream_index = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_language(mut self, value: Option<[u8; 3]>) -> Self {
self.language = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_forced(mut self, value: bool) -> Self {
self.forced = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
self.stream_index = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_language(&mut self, value: Option<[u8; 3]>) -> &mut Self {
self.language = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_forced(&mut self, value: bool) -> &mut Self {
self.forced = value;
self
}
}
#[derive(Clone, Debug, Default)]
pub struct SubtitleFrameExtra {
start_display_time: u32,
end_display_time: u32,
}
impl SubtitleFrameExtra {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(start_display_time: u32, end_display_time: u32) -> Self {
Self {
start_display_time,
end_display_time,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn start_display_time(&self) -> u32 {
self.start_display_time
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn end_display_time(&self) -> u32 {
self.end_display_time
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_start_display_time(mut self, value: u32) -> Self {
self.start_display_time = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_end_display_time(mut self, value: u32) -> Self {
self.end_display_time = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_start_display_time(&mut self, value: u32) -> &mut Self {
self.start_display_time = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_end_display_time(&mut self, value: u32) -> &mut Self {
self.end_display_time = value;
self
}
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[non_exhaustive]
pub enum PictureType {
#[default]
Unspecified,
I,
P,
B,
S,
Si,
Sp,
Bi,
}
#[derive(Clone, Debug)]
pub struct SideDataEntry {
kind: i32,
data: Vec<u8>,
}
impl SideDataEntry {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(kind: i32, data: Vec<u8>) -> Self {
Self { kind, data }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn kind(&self) -> i32 {
self.kind
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn data(&self) -> &[u8] {
self.data.as_slice()
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_kind(mut self, value: i32) -> Self {
self.kind = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub fn with_data(mut self, value: Vec<u8>) -> Self {
self.data = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_kind(&mut self, value: i32) -> &mut Self {
self.kind = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_data(&mut self, value: Vec<u8>) -> &mut Self {
self.data = value;
self
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct MasteringDisplay {
display_primaries: [(u32, u32); 3],
white_point: (u32, u32),
max_luminance: (u32, u32),
min_luminance: (u32, u32),
}
impl MasteringDisplay {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(
display_primaries: [(u32, u32); 3],
white_point: (u32, u32),
max_luminance: (u32, u32),
min_luminance: (u32, u32),
) -> Self {
Self {
display_primaries,
white_point,
max_luminance,
min_luminance,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn display_primaries(&self) -> [(u32, u32); 3] {
self.display_primaries
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn white_point(&self) -> (u32, u32) {
self.white_point
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn max_luminance(&self) -> (u32, u32) {
self.max_luminance
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn min_luminance(&self) -> (u32, u32) {
self.min_luminance
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_display_primaries(mut self, value: [(u32, u32); 3]) -> Self {
self.display_primaries = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_white_point(mut self, value: (u32, u32)) -> Self {
self.white_point = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_max_luminance(mut self, value: (u32, u32)) -> Self {
self.max_luminance = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_min_luminance(mut self, value: (u32, u32)) -> Self {
self.min_luminance = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_display_primaries(&mut self, value: [(u32, u32); 3]) -> &mut Self {
self.display_primaries = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_white_point(&mut self, value: (u32, u32)) -> &mut Self {
self.white_point = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_max_luminance(&mut self, value: (u32, u32)) -> &mut Self {
self.max_luminance = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_min_luminance(&mut self, value: (u32, u32)) -> &mut Self {
self.min_luminance = value;
self
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct ContentLightLevel {
max_cll: u32,
max_fall: u32,
}
impl ContentLightLevel {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(max_cll: u32, max_fall: u32) -> Self {
Self { max_cll, max_fall }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn max_cll(&self) -> u32 {
self.max_cll
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn max_fall(&self) -> u32 {
self.max_fall
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_max_cll(mut self, value: u32) -> Self {
self.max_cll = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[must_use]
pub const fn with_max_fall(mut self, value: u32) -> Self {
self.max_fall = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_max_cll(&mut self, value: u32) -> &mut Self {
self.max_cll = value;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_max_fall(&mut self, value: u32) -> &mut Self {
self.max_fall = value;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults_construct() {
let v = VideoPacketExtra::default();
assert_eq!(v.stream_index(), 0);
assert!(v.side_data().is_empty());
let f = VideoFrameExtra::default();
assert_eq!(f.picture_type(), PictureType::Unspecified);
assert!(!f.key_frame());
assert!(f.mastering_display().is_none());
let s = SubtitleFrameExtra::default();
assert_eq!(s.start_display_time(), 0);
assert_eq!(s.end_display_time(), 0);
}
#[test]
fn picture_type_default_is_unspecified() {
assert_eq!(PictureType::default(), PictureType::Unspecified);
}
#[test]
fn side_data_entry_carries_bytes() {
let entry = SideDataEntry::new(12345, vec![1, 2, 3, 4]);
assert_eq!(entry.kind(), 12345);
assert_eq!(entry.data(), &[1, 2, 3, 4]);
}
#[test]
fn content_light_level_default_is_zero() {
let cll = ContentLightLevel::default();
assert_eq!(cll.max_cll(), 0);
assert_eq!(cll.max_fall(), 0);
}
#[test]
fn builders_chain() {
let v = VideoPacketExtra::new(7)
.with_byte_pos(Some(1234))
.with_side_data(vec![SideDataEntry::new(1, vec![0xAB])]);
assert_eq!(v.stream_index(), 7);
assert_eq!(v.byte_pos(), Some(1234));
assert_eq!(v.side_data().len(), 1);
}
#[test]
fn setters_chain() {
let mut v = VideoPacketExtra::default();
v.set_stream_index(3).set_byte_pos(Some(99));
assert_eq!(v.stream_index(), 3);
assert_eq!(v.byte_pos(), Some(99));
}
}