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