1#![warn(missing_docs)]
51#![warn(clippy::all)]
52#![warn(clippy::pedantic)]
53
54pub mod channel;
56pub mod chapter;
57pub mod codec;
58pub mod color;
59pub mod container;
60pub mod error;
61pub mod frame;
62pub mod hdr;
63pub mod media;
64pub mod pixel;
65pub mod sample;
66pub mod stream;
67pub mod time;
68
69pub use channel::ChannelLayout;
70pub use chapter::{ChapterInfo, ChapterInfoBuilder};
71pub use codec::{AudioCodec, SubtitleCodec, VideoCodec};
72pub use color::{ColorPrimaries, ColorRange, ColorSpace, ColorTransfer};
73pub use container::{ContainerInfo, ContainerInfoBuilder};
74pub use error::{FormatError, FrameError};
75pub use ff_common::PooledBuffer;
76pub use frame::{AudioFrame, VideoFrame};
77pub use hdr::{Hdr10Metadata, MasteringDisplay};
78pub use media::{MediaInfo, MediaInfoBuilder};
79pub use pixel::PixelFormat;
80pub use sample::SampleFormat;
81pub use stream::{
82 AudioStreamInfo, AudioStreamInfoBuilder, SubtitleStreamInfo, SubtitleStreamInfoBuilder,
83 VideoStreamInfo, VideoStreamInfoBuilder,
84};
85pub use time::{Rational, Timestamp};
86
87pub mod prelude {
95 pub use crate::{
96 AudioCodec, AudioFrame, AudioStreamInfo, ChannelLayout, ChapterInfo, ColorPrimaries,
97 ColorRange, ColorSpace, FormatError, FrameError, MediaInfo, PixelFormat, PooledBuffer,
98 Rational, SampleFormat, Timestamp, VideoCodec, VideoFrame, VideoStreamInfo,
99 };
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_prelude_exports() {
108 let _pixel: PixelFormat = PixelFormat::default();
110 let _sample: SampleFormat = SampleFormat::default();
111 let _rational: Rational = Rational::default();
112 let _timestamp: Timestamp = Timestamp::default();
113 let _video_frame: VideoFrame = VideoFrame::default();
114 let _audio_frame: AudioFrame = AudioFrame::default();
115
116 let _color_space: ColorSpace = ColorSpace::default();
118 let _color_range: ColorRange = ColorRange::default();
119 let _color_primaries: ColorPrimaries = ColorPrimaries::default();
120 let _video_codec: VideoCodec = VideoCodec::default();
121 let _audio_codec: AudioCodec = AudioCodec::default();
122 let _channel_layout: ChannelLayout = ChannelLayout::default();
123 let _video_stream: VideoStreamInfo = VideoStreamInfo::default();
124 let _audio_stream: AudioStreamInfo = AudioStreamInfo::default();
125 let _media_info: MediaInfo = MediaInfo::default();
126 }
127
128 #[test]
129 fn test_stream_info_builder() {
130 let video = VideoStreamInfo::builder()
132 .index(0)
133 .codec(VideoCodec::H264)
134 .width(1920)
135 .height(1080)
136 .frame_rate(Rational::new(30, 1))
137 .pixel_format(PixelFormat::Yuv420p)
138 .color_space(ColorSpace::Bt709)
139 .build();
140
141 assert_eq!(video.width(), 1920);
142 assert_eq!(video.height(), 1080);
143 assert_eq!(video.codec(), VideoCodec::H264);
144 assert_eq!(video.color_space(), ColorSpace::Bt709);
145
146 let audio = AudioStreamInfo::builder()
148 .index(1)
149 .codec(AudioCodec::Aac)
150 .sample_rate(48000)
151 .channels(2)
152 .sample_format(SampleFormat::F32)
153 .build();
154
155 assert_eq!(audio.sample_rate(), 48000);
156 assert_eq!(audio.channels(), 2);
157 assert_eq!(audio.codec(), AudioCodec::Aac);
158 assert_eq!(audio.channel_layout(), ChannelLayout::Stereo);
159 }
160
161 #[test]
162 fn test_media_info_builder() {
163 use std::time::Duration;
164
165 let video = VideoStreamInfo::builder()
167 .index(0)
168 .codec(VideoCodec::H264)
169 .width(1920)
170 .height(1080)
171 .frame_rate(Rational::new(30, 1))
172 .build();
173
174 let audio = AudioStreamInfo::builder()
175 .index(1)
176 .codec(AudioCodec::Aac)
177 .sample_rate(48000)
178 .channels(2)
179 .build();
180
181 let media = MediaInfo::builder()
183 .path("/path/to/video.mp4")
184 .format("mp4")
185 .format_long_name("QuickTime / MOV")
186 .duration(Duration::from_secs(120))
187 .file_size(100_000_000)
188 .bitrate(8_000_000)
189 .video_stream(video)
190 .audio_stream(audio)
191 .metadata("title", "Test Video")
192 .build();
193
194 assert!(media.has_video());
195 assert!(media.has_audio());
196 assert_eq!(media.resolution(), Some((1920, 1080)));
197 assert!((media.frame_rate().unwrap() - 30.0).abs() < 0.001);
198 assert_eq!(media.sample_rate(), Some(48000));
199 assert_eq!(media.channels(), Some(2));
200 assert_eq!(media.format(), "mp4");
201 assert_eq!(media.format_long_name(), Some("QuickTime / MOV"));
202 assert_eq!(media.metadata_value("title"), Some("Test Video"));
203 }
204}