1 | // Copyright (c) 2017-2022, The rav1e contributors. All rights reserved |
2 | // |
3 | // This source code is subject to the terms of the BSD 2 Clause License and |
4 | // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
5 | // was not distributed with this source code in the LICENSE file, you can |
6 | // obtain it at www.aomedia.org/license/software. If the Alliance for Open |
7 | // Media Patent License 1.0 was not distributed with this source code in the |
8 | // PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
9 | |
10 | //! rav1e is an [AV1] video encoder. It is designed to eventually cover all use |
11 | //! cases, though in its current form it is most suitable for cases where |
12 | //! libaom (the reference encoder) is too slow. |
13 | //! |
14 | //! ## Features |
15 | //! |
16 | //! * Intra and inter frames |
17 | //! * 64x64 superblocks |
18 | //! * 4x4 to 64x64 RDO-selected square and 2:1/1:2 rectangular blocks |
19 | //! * DC, H, V, Paeth, smooth, and a subset of directional prediction modes |
20 | //! * DCT, (FLIP-)ADST and identity transforms (up to 64x64, 16x16 and 32x32 |
21 | //! respectively) |
22 | //! * 8-, 10- and 12-bit depth color |
23 | //! * 4:2:0 (full support), 4:2:2 and 4:4:4 (limited) chroma sampling |
24 | //! * Variable speed settings |
25 | //! * Near real-time encoding at high speed levels |
26 | //! |
27 | //! ## Usage |
28 | //! |
29 | //! Encoding is done through the [`Context`] struct. Examples on |
30 | //! [`Context::receive_packet`] show how to create a [`Context`], send frames |
31 | //! into it and receive packets of encoded data. |
32 | //! |
33 | //! [AV1]: https://aomediacodec.github.io/av1-spec/av1-spec.pdf |
34 | //! [`Context`]: struct.Context.html |
35 | //! [`Context::receive_packet`]: struct.Context.html#method.receive_packet |
36 | |
37 | // Safety lints |
38 | #![deny (bare_trait_objects)] |
39 | #![deny (clippy::as_ptr_cast_mut)] |
40 | #![deny (clippy::large_stack_arrays)] |
41 | // Performance lints |
42 | #![warn (clippy::inefficient_to_string)] |
43 | #![warn (clippy::invalid_upcast_comparisons)] |
44 | #![warn (clippy::iter_with_drain)] |
45 | #![warn (clippy::linkedlist)] |
46 | #![warn (clippy::mutex_integer)] |
47 | #![warn (clippy::naive_bytecount)] |
48 | #![warn (clippy::needless_bitwise_bool)] |
49 | #![warn (clippy::needless_collect)] |
50 | #![warn (clippy::or_fun_call)] |
51 | #![warn (clippy::stable_sort_primitive)] |
52 | #![warn (clippy::suboptimal_flops)] |
53 | #![warn (clippy::trivial_regex)] |
54 | #![warn (clippy::trivially_copy_pass_by_ref)] |
55 | #![warn (clippy::unnecessary_join)] |
56 | #![warn (clippy::unused_async)] |
57 | #![warn (clippy::zero_sized_map_values)] |
58 | // Correctness lints |
59 | #![deny (clippy::case_sensitive_file_extension_comparisons)] |
60 | #![deny (clippy::copy_iterator)] |
61 | #![deny (clippy::expl_impl_clone_on_copy)] |
62 | #![deny (clippy::float_cmp)] |
63 | #![warn (clippy::imprecise_flops)] |
64 | #![deny (clippy::manual_instant_elapsed)] |
65 | #![deny (clippy::mem_forget)] |
66 | #![deny (clippy::path_buf_push_overwrite)] |
67 | #![deny (clippy::same_functions_in_if_condition)] |
68 | #![deny (clippy::unchecked_duration_subtraction)] |
69 | #![deny (clippy::unicode_not_nfc)] |
70 | // Clarity/formatting lints |
71 | #![warn (clippy::checked_conversions)] |
72 | #![allow (clippy::comparison_chain)] |
73 | #![warn (clippy::derive_partial_eq_without_eq)] |
74 | #![allow (clippy::enum_variant_names)] |
75 | #![warn (clippy::explicit_deref_methods)] |
76 | #![warn (clippy::filter_map_next)] |
77 | #![warn (clippy::flat_map_option)] |
78 | #![warn (clippy::fn_params_excessive_bools)] |
79 | #![warn (clippy::implicit_clone)] |
80 | #![warn (clippy::iter_not_returning_iterator)] |
81 | #![warn (clippy::iter_on_empty_collections)] |
82 | #![warn (clippy::macro_use_imports)] |
83 | #![warn (clippy::manual_clamp)] |
84 | #![warn (clippy::manual_let_else)] |
85 | #![warn (clippy::manual_ok_or)] |
86 | #![warn (clippy::manual_string_new)] |
87 | #![warn (clippy::map_flatten)] |
88 | #![warn (clippy::match_bool)] |
89 | #![warn (clippy::mut_mut)] |
90 | #![warn (clippy::needless_borrow)] |
91 | #![warn (clippy::needless_continue)] |
92 | #![allow (clippy::needless_range_loop)] |
93 | #![allow (clippy::too_many_arguments)] |
94 | #![warn (clippy::range_minus_one)] |
95 | #![warn (clippy::range_plus_one)] |
96 | #![warn (clippy::ref_binding_to_reference)] |
97 | #![warn (clippy::ref_option_ref)] |
98 | #![warn (clippy::trait_duplication_in_bounds)] |
99 | #![warn (clippy::unused_peekable)] |
100 | #![warn (clippy::unused_rounding)] |
101 | #![warn (clippy::unused_self)] |
102 | #![allow (clippy::upper_case_acronyms)] |
103 | #![warn (clippy::verbose_bit_mask)] |
104 | #![warn (clippy::verbose_file_reads)] |
105 | // Documentation lints |
106 | #![warn (clippy::doc_link_with_quotes)] |
107 | #![warn (clippy::doc_markdown)] |
108 | #![warn (clippy::missing_errors_doc)] |
109 | #![warn (clippy::missing_panics_doc)] |
110 | // FIXME: We should fix instances of this lint and change it to `warn` |
111 | #![allow (clippy::missing_safety_doc)] |
112 | |
113 | // Override assert! and assert_eq! in tests |
114 | #[cfg (test)] |
115 | #[macro_use ] |
116 | extern crate pretty_assertions; |
117 | |
118 | #[macro_use ] |
119 | extern crate log; |
120 | |
121 | pub(crate) mod built_info { |
122 | // The file has been placed there by the build script. |
123 | include!(concat!(env!("OUT_DIR" ) , "/built.rs" )); |
124 | } |
125 | |
126 | mod serialize { |
127 | cfg_if::cfg_if! { |
128 | if #[cfg(feature="serialize" )] { |
129 | pub use serde::*; |
130 | } else { |
131 | pub use noop_proc_macro::{Deserialize, Serialize}; |
132 | } |
133 | } |
134 | } |
135 | |
136 | mod wasm_bindgen { |
137 | cfg_if::cfg_if! { |
138 | if #[cfg(feature="wasm" )] { |
139 | pub use wasm_bindgen::prelude::*; |
140 | } else { |
141 | pub use noop_proc_macro::wasm_bindgen; |
142 | } |
143 | } |
144 | } |
145 | |
146 | #[cfg (any(cargo_c, feature = "capi" ))] |
147 | pub mod capi; |
148 | |
149 | #[macro_use ] |
150 | mod transform; |
151 | #[macro_use ] |
152 | mod cpu_features; |
153 | |
154 | mod activity; |
155 | pub(crate) mod asm; |
156 | mod dist; |
157 | mod ec; |
158 | mod partition; |
159 | mod predict; |
160 | mod quantize; |
161 | mod rdo; |
162 | mod rdo_tables; |
163 | #[macro_use ] |
164 | mod util; |
165 | mod cdef; |
166 | #[doc (hidden)] |
167 | pub mod context; |
168 | mod deblock; |
169 | mod encoder; |
170 | mod entropymode; |
171 | mod levels; |
172 | mod lrf; |
173 | mod mc; |
174 | mod me; |
175 | mod rate; |
176 | mod recon_intra; |
177 | mod sad_plane; |
178 | mod scan_order; |
179 | #[cfg (feature = "scenechange" )] |
180 | pub mod scenechange; |
181 | #[cfg (not(feature = "scenechange" ))] |
182 | mod scenechange; |
183 | mod segmentation; |
184 | mod stats; |
185 | #[doc (hidden)] |
186 | pub mod tiling; |
187 | mod token_cdfs; |
188 | |
189 | mod api; |
190 | mod frame; |
191 | mod header; |
192 | |
193 | use crate::encoder::*; |
194 | |
195 | pub use crate::api::{ |
196 | Config, Context, EncoderConfig, EncoderStatus, InvalidConfig, Packet, |
197 | }; |
198 | pub use crate::frame::Frame; |
199 | pub use crate::util::{CastFromPrimitive, Pixel, PixelType}; |
200 | |
201 | /// Commonly used types and traits. |
202 | pub mod prelude { |
203 | pub use crate::api::*; |
204 | pub use crate::encoder::{Sequence, Tune}; |
205 | pub use crate::frame::{ |
206 | Frame, FrameParameters, FrameTypeOverride, Plane, PlaneConfig, |
207 | }; |
208 | pub use crate::partition::BlockSize; |
209 | pub use crate::predict::PredictionMode; |
210 | pub use crate::transform::TxType; |
211 | pub use crate::util::{CastFromPrimitive, Pixel, PixelType}; |
212 | } |
213 | |
214 | /// Basic data structures |
215 | pub mod data { |
216 | pub use crate::api::{ |
217 | ChromaticityPoint, EncoderStatus, FrameType, Packet, Rational, |
218 | }; |
219 | pub use crate::frame::{Frame, FrameParameters}; |
220 | pub use crate::stats::EncoderStats; |
221 | pub use crate::util::{CastFromPrimitive, Pixel, PixelType}; |
222 | } |
223 | |
224 | pub use crate::api::color; |
225 | |
226 | /// Encoder configuration and settings |
227 | pub mod config { |
228 | pub use crate::api::config::{ |
229 | GrainTableSegment, NoiseGenArgs, TransferFunction, NUM_UV_COEFFS, |
230 | NUM_UV_POINTS, NUM_Y_COEFFS, NUM_Y_POINTS, |
231 | }; |
232 | pub use crate::api::{ |
233 | Config, EncoderConfig, InvalidConfig, PredictionModesSetting, |
234 | RateControlConfig, RateControlError, RateControlSummary, SpeedSettings, |
235 | }; |
236 | pub use crate::cpu_features::CpuFeatureLevel; |
237 | } |
238 | |
239 | /// Version information |
240 | /// |
241 | /// The information is recovered from `Cargo.toml` and `git describe`, when available. |
242 | /// |
243 | /// ``` |
244 | /// use rav1e::version; |
245 | /// use semver::Version; |
246 | /// |
247 | /// let major = version::major(); |
248 | /// let minor = version::minor(); |
249 | /// let patch = version::patch(); |
250 | /// |
251 | /// let short = version::short(); |
252 | /// |
253 | /// let v1 = Version::new(major, minor, patch); |
254 | /// let v2 = Version::parse(&short).unwrap(); |
255 | /// |
256 | /// assert_eq!(v1.major, v2.major); |
257 | /// ``` |
258 | pub mod version { |
259 | /// Major version component |
260 | /// |
261 | /// It is increased every time a release presents a incompatible API change. |
262 | /// |
263 | /// # Panics |
264 | /// |
265 | /// Will panic if package is not built with Cargo, |
266 | /// or if the package version is not a valid triplet of integers. |
267 | pub fn major() -> u64 { |
268 | env!("CARGO_PKG_VERSION_MAJOR" ).parse().unwrap() |
269 | } |
270 | /// Minor version component |
271 | /// |
272 | /// It is increased every time a release presents new functionalities are added |
273 | /// in a backwards-compatible manner. |
274 | /// |
275 | /// # Panics |
276 | /// |
277 | /// Will panic if package is not built with Cargo, |
278 | /// or if the package version is not a valid triplet of integers. |
279 | pub fn minor() -> u64 { |
280 | env!("CARGO_PKG_VERSION_MINOR" ).parse().unwrap() |
281 | } |
282 | /// Patch version component |
283 | /// |
284 | /// It is increased every time a release provides only backwards-compatible bugfixes. |
285 | /// |
286 | /// # Panics |
287 | /// |
288 | /// Will panic if package is not built with Cargo, |
289 | /// or if the package version is not a valid triplet of integers. |
290 | pub fn patch() -> u64 { |
291 | env!("CARGO_PKG_VERSION_PATCH" ).parse().unwrap() |
292 | } |
293 | |
294 | /// Version information as presented in `[package]` `version`. |
295 | /// |
296 | /// e.g. `0.1.0` |
297 | /// |
298 | /// Can be parsed by [semver](https://crates.io/crates/semver). |
299 | pub fn short() -> String { |
300 | env!("CARGO_PKG_VERSION" ).to_string() |
301 | } |
302 | |
303 | /// Version information as presented in `[package] version` followed by the |
304 | /// short commit hash if present. |
305 | /// |
306 | /// e.g. `0.1.0 - g743d464` |
307 | /// |
308 | pub fn long() -> String { |
309 | let s = short(); |
310 | let hash = hash(); |
311 | |
312 | if hash.is_empty() { |
313 | s |
314 | } else { |
315 | format!(" {s} - {hash}" ) |
316 | } |
317 | } |
318 | |
319 | cfg_if::cfg_if! { |
320 | if #[cfg(feature="git_version" )] { |
321 | fn git_version() -> &'static str { |
322 | crate::built_info::GIT_VERSION.unwrap_or_default() |
323 | } |
324 | |
325 | fn git_hash() -> &'static str { |
326 | crate::built_info::GIT_COMMIT_HASH.unwrap_or_default() |
327 | } |
328 | } else { |
329 | fn git_version() -> &'static str { |
330 | "UNKNOWN" |
331 | } |
332 | |
333 | fn git_hash() -> &'static str { |
334 | "UNKNOWN" |
335 | } |
336 | } |
337 | } |
338 | /// Commit hash (short) |
339 | /// |
340 | /// Short hash of the git commit used by this build |
341 | /// |
342 | /// e.g. `g743d464` |
343 | /// |
344 | pub fn hash() -> String { |
345 | git_hash().to_string() |
346 | } |
347 | |
348 | /// Version information with the information |
349 | /// provided by `git describe --tags`. |
350 | /// |
351 | /// e.g. `0.1.0 (v0.1.0-1-g743d464)` |
352 | /// |
353 | pub fn full() -> String { |
354 | format!(" {} ( {})" , short(), git_version(),) |
355 | } |
356 | } |
357 | #[cfg (all( |
358 | any(test, fuzzing), |
359 | any(feature = "decode_test" , feature = "decode_test_dav1d" ) |
360 | ))] |
361 | mod test_encode_decode; |
362 | |
363 | #[cfg (feature = "bench" )] |
364 | pub mod bench { |
365 | pub mod api { |
366 | pub use crate::api::*; |
367 | } |
368 | pub mod cdef { |
369 | pub use crate::cdef::*; |
370 | } |
371 | pub mod context { |
372 | pub use crate::context::*; |
373 | } |
374 | pub mod dist { |
375 | pub use crate::dist::*; |
376 | } |
377 | pub mod ec { |
378 | pub use crate::ec::*; |
379 | } |
380 | pub mod encoder { |
381 | pub use crate::encoder::*; |
382 | } |
383 | pub mod mc { |
384 | pub use crate::mc::*; |
385 | } |
386 | pub mod partition { |
387 | pub use crate::partition::*; |
388 | } |
389 | pub mod frame { |
390 | pub use crate::frame::*; |
391 | } |
392 | pub mod predict { |
393 | pub use crate::predict::*; |
394 | } |
395 | pub mod rdo { |
396 | pub use crate::rdo::*; |
397 | } |
398 | pub mod tiling { |
399 | pub use crate::tiling::*; |
400 | } |
401 | pub mod transform { |
402 | pub use crate::transform::*; |
403 | } |
404 | pub mod util { |
405 | pub use crate::util::*; |
406 | } |
407 | pub mod cpu_features { |
408 | pub use crate::cpu_features::*; |
409 | } |
410 | } |
411 | |
412 | #[cfg (fuzzing)] |
413 | pub mod fuzzing; |
414 | |