| 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 | |