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