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