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