oximedia_codec/rate_control/
mod.rs1#![allow(clippy::cast_lossless)]
3#![allow(clippy::cast_precision_loss)]
4#![allow(clippy::cast_possible_truncation)]
5#![allow(clippy::cast_sign_loss)]
6#![allow(clippy::similar_names)]
7#![allow(clippy::unused_self)]
8
9#![forbid(unsafe_code)]
116
117pub mod abr;
118pub mod allocation;
119pub mod analysis;
120pub mod aq;
121pub mod buffer;
122pub mod cbr;
123pub mod complexity;
124pub mod cqp;
125pub mod crf;
126pub mod lookahead;
127pub mod quantizer;
128pub mod scene_adaptive;
129pub mod simple_rc;
130pub mod types;
131pub mod vbr;
132
133pub use abr::{
135 AbrController, FirstPassStats as AbrFirstPassStats, FramePassStats as AbrFramePassStats,
136};
137pub use allocation::{AllocationResult, AllocationStrategy, BitrateAllocator, GopAllocationStatus};
138pub use analysis::{
139 AnalysisResult, ContentAnalyzer, ContentType, SceneChangeThreshold, TextureMetrics,
140};
141pub use aq::{AdaptiveQuantization, AqMode, AqResult, AqStrength};
142pub use buffer::{BufferModel, RateBuffer, VbvParams};
143pub use cbr::CbrController;
144pub use complexity::{ComplexityEstimator, ComplexityResult, MotionAnalyzer, MotionResult};
145pub use cqp::CqpController;
146pub use crf::{CrfController, QualityPreset};
147pub use lookahead::{
148 AdaptiveAllocation, ContentAdaptiveAllocator, ContentMetrics, Lookahead, LookaheadFrame,
149 MiniGopInfo, SceneChangeDetector, SceneContentType,
150};
151pub use quantizer::{BlockQpMap, QpResult, QpSelector, QpStrategy};
152pub use scene_adaptive::{
153 FrameBitTarget, FrameContentMetrics, Scene as AdaptiveScene, SceneAdaptiveAllocator,
154 SceneAdaptiveConfig, SceneContentType as SceneAdaptiveContentType,
155};
156pub use simple_rc::{
157 SimpleRateControlConfig, SimpleRateControlMode, SimpleRateControlStats, SimpleRateController,
158};
159pub use types::{
160 FrameStats, GopStats, RateControlMode, RcConfig, RcConfigError, RcOutput, RcState,
161};
162pub use vbr::{FirstPassData, VbrController};
163
164#[must_use]
178pub fn create_controller(config: &RcConfig) -> Box<dyn RateController> {
179 match config.mode {
180 RateControlMode::Cqp => Box::new(CqpController::new(config)),
181 RateControlMode::Cbr => Box::new(CbrController::new(config)),
182 RateControlMode::Vbr | RateControlMode::Abr => Box::new(VbrController::new(config)),
183 RateControlMode::Crf => Box::new(CrfController::new(config)),
184 }
185}
186
187pub trait RateController: Send {
189 fn get_output(&mut self, frame_type: crate::frame::FrameType, complexity: f32) -> RcOutput;
191
192 fn update_stats(&mut self, stats: &FrameStats);
194
195 fn reset(&mut self);
197
198 fn current_qp(&self) -> f32;
200
201 fn frame_count(&self) -> u64;
203
204 fn total_bits(&self) -> u64;
206}
207
208impl RateController for CqpController {
209 fn get_output(&mut self, frame_type: crate::frame::FrameType, _complexity: f32) -> RcOutput {
210 self.get_qp(frame_type)
211 }
212
213 fn update_stats(&mut self, stats: &FrameStats) {
214 self.update(stats);
215 }
216
217 fn reset(&mut self) {
218 CqpController::reset(self);
219 }
220
221 fn current_qp(&self) -> f32 {
222 self.base_qp() as f32
223 }
224
225 fn frame_count(&self) -> u64 {
226 CqpController::frame_count(self)
227 }
228
229 fn total_bits(&self) -> u64 {
230 CqpController::total_bits(self)
231 }
232}
233
234impl RateController for CbrController {
235 fn get_output(&mut self, frame_type: crate::frame::FrameType, _complexity: f32) -> RcOutput {
236 self.get_rc(frame_type)
237 }
238
239 fn update_stats(&mut self, stats: &FrameStats) {
240 self.update(stats);
241 }
242
243 fn reset(&mut self) {
244 CbrController::reset(self);
245 }
246
247 fn current_qp(&self) -> f32 {
248 CbrController::current_qp(self)
249 }
250
251 fn frame_count(&self) -> u64 {
252 CbrController::frame_count(self)
253 }
254
255 fn total_bits(&self) -> u64 {
256 0
258 }
259}
260
261impl RateController for VbrController {
262 fn get_output(&mut self, frame_type: crate::frame::FrameType, complexity: f32) -> RcOutput {
263 self.get_rc(frame_type, complexity)
264 }
265
266 fn update_stats(&mut self, stats: &FrameStats) {
267 self.update(stats);
268 }
269
270 fn reset(&mut self) {
271 VbrController::reset(self);
272 }
273
274 fn current_qp(&self) -> f32 {
275 VbrController::current_qp(self)
276 }
277
278 fn frame_count(&self) -> u64 {
279 VbrController::frame_count(self)
280 }
281
282 fn total_bits(&self) -> u64 {
283 0
284 }
285}
286
287impl RateController for CrfController {
288 fn get_output(&mut self, frame_type: crate::frame::FrameType, complexity: f32) -> RcOutput {
289 self.get_rc(frame_type, complexity)
290 }
291
292 fn update_stats(&mut self, stats: &FrameStats) {
293 self.update(stats);
294 }
295
296 fn reset(&mut self) {
297 CrfController::reset(self);
298 }
299
300 fn current_qp(&self) -> f32 {
301 CrfController::current_qp(self)
302 }
303
304 fn frame_count(&self) -> u64 {
305 CrfController::frame_count(self)
306 }
307
308 fn total_bits(&self) -> u64 {
309 CrfController::total_bits(self)
310 }
311}
312
313#[cfg(test)]
314mod tests {
315 use super::*;
316 use crate::frame::FrameType;
317
318 #[test]
319 fn test_create_controller_cqp() {
320 let config = RcConfig::cqp(28);
321 let mut controller = create_controller(&config);
322
323 let output = controller.get_output(FrameType::Key, 1.0);
324 assert_eq!(output.qp, 28);
325 }
326
327 #[test]
328 fn test_create_controller_cbr() {
329 let config = RcConfig::cbr(5_000_000);
330 let mut controller = create_controller(&config);
331
332 let output = controller.get_output(FrameType::Key, 1.0);
333 assert!(!output.drop_frame);
334 assert!(output.target_bits > 0);
335 }
336
337 #[test]
338 fn test_create_controller_vbr() {
339 let config = RcConfig::vbr(5_000_000, 10_000_000);
340 let mut controller = create_controller(&config);
341
342 let output = controller.get_output(FrameType::Key, 1.0);
343 assert!(output.target_bits > 0);
344 }
345
346 #[test]
347 fn test_create_controller_crf() {
348 let config = RcConfig::crf(23.0);
349 let mut controller = create_controller(&config);
350
351 let output = controller.get_output(FrameType::Key, 1.0);
352 assert!(output.qp > 0);
353 }
354
355 #[test]
356 fn test_controller_trait_update() {
357 let config = RcConfig::cqp(28);
358 let mut controller = create_controller(&config);
359
360 let mut stats = FrameStats::new(0, FrameType::Key);
361 stats.bits = 100_000;
362 stats.qp_f = 28.0;
363
364 controller.update_stats(&stats);
365 assert_eq!(controller.frame_count(), 1);
366 }
367
368 #[test]
369 fn test_controller_trait_reset() {
370 let config = RcConfig::cqp(28);
371 let mut controller = create_controller(&config);
372
373 let mut stats = FrameStats::new(0, FrameType::Key);
374 stats.bits = 100_000;
375 controller.update_stats(&stats);
376
377 controller.reset();
378 assert_eq!(controller.frame_count(), 0);
379 }
380
381 #[test]
382 fn test_all_modes_covered() {
383 for mode in [
384 RateControlMode::Cqp,
385 RateControlMode::Cbr,
386 RateControlMode::Vbr,
387 RateControlMode::Abr,
388 RateControlMode::Crf,
389 ] {
390 let config = RcConfig {
391 mode,
392 target_bitrate: 5_000_000,
393 ..Default::default()
394 };
395
396 let mut controller = create_controller(&config);
397 let output = controller.get_output(FrameType::Inter, 1.0);
398
399 assert!(output.qp > 0 || output.drop_frame);
401 }
402 }
403}