### Parse Command-Line Arguments (Rust) Source: https://context7.com/emrakyz/xav/llms.txt This snippet illustrates how to parse command-line arguments for the Xav project, including various encoding parameters and their automatic default values. It defines the structure of expected arguments and provides examples of command-line usage. ```rust use std::path::PathBuf; // Parse command-line arguments let args = parse_args(); // Arguments include: // - worker: Number of parallel encoder instances // - scene_file: Path to scene detection file // - params: SVT-AV1 encoder parameters // - input: Input video file // - output: Output video file // - resume: Resume incomplete encoding // - quiet: Disable progress display // - noise: ISO value for film grain (1-64) // - audio: Audio encoding specification // - chunk_buffer: Additional chunks to buffer ahead // - target_quality: Quality metric target range (with vship feature) // - metric_mode: Score aggregation method (with vship feature) // - qp_range: CRF search range (with vship feature) // - metric_worker: Number of VSHIP instances (with vship feature) // Automatic defaults applied: // - Workers: 1 worker with "--lp 1" if not specified // - Params: "--lp N" prepended based on worker count // - Output: input_av1.mkv if not specified // - Scene file: input_scd.txt if not specified // - QP range: "8.0-48.0" if target quality specified // - Metric workers: 3 if target quality specified // - Chunk buffer: worker count + extra buffer // Example usage from command line: // xav -w 8 -p "--preset 6" input.mkv output.mkv // xav -r input.mkv (resume encoding) // xav -n 16 -a "auto all" input.mkv (noise + audio) // xav -t "82.0-84.0" -m "mean" input.mkv (target quality) // xav -b 4 input.mkv (extra 4 chunk buffer) ``` -------------------------------- ### Real-time Encoding Progress Monitoring (Rust) Source: https://context7.com/emrakyz/xav/llms.txt Tracks encoding progress in real-time using multi-worker displays. It shows detailed statistics for scene detection, indexing, encoding progress per chunk, aggregate FPS, bitrate estimates, target quality metrics, and estimated final size. ```rust use std::sync::{Arc, atomic::AtomicUsize, Mutex}; // Progress bars show: // - Scene detection: FPS, ETA, percentage // - Indexing: MB/s, ETA, progress // - Encoding: per-chunk progress, aggregate FPS, bitrate estimates // - Target quality: probe rounds, CRF values, metric scores // Scene detection progress let mut prog = progs::ProgsBar::new(false); prog.up_scenes(1500, 5000); // 1500 of 5000 frames prog.finish_scenes(); // Multi-worker encoding progress let completed = Arc::new(AtomicUsize::new(0)); let completions = Arc::new(Mutex::new(chunk::ResumeInf { chnks_done: Vec::new() })); let tracker = progs::ProgsTrack::new( &chunks, &inf, 8, // worker count 0, // initial frames completed, completions, ); // Progress automatically updates as workers report frames // Shows: elapsed time, chunks done/total, progress bar, // FPS, ETA, bitrate, estimated final size #[cfg(feature = "vship")] { // Target quality progress shows per-worker metric computation tracker.show_metric_progress( 0, // worker_id 5, // chunk_idx (42, 100), // (current_frame, total_frames) 120.5, // fps (28.5, Some(82.34)), // (crf, last_score) ); } ``` -------------------------------- ### Generate SVT-AV1 Encoder Commands (Rust) Source: https://context7.com/emrakyz/xav/llms.txt Generates SVT-AV1 encoder commands with automatic metadata propagation. This includes resolution, framerate, color information, HDR metadata, and film grain settings. The output is a command string suitable for execution. ```rust use std::process::Command; // Configuration automatically includes: // - Resolution and framerate from source // - Color primaries, transfer characteristics, matrix coefficients // - HDR mastering display and content light level metadata // - Chroma sample position // - Keyframe and scene detection settings // - Film grain table if specified // Generated command example for 1920x1080 23.976fps HDR content with grain: // SvtAv1EncApp -i stdin --input-depth 10 --width 1920 // --forced-max-frame-width 1920 --height 1080 // --forced-max-frame-height 1080 --fps-num 24000 // --fps-denom 1001 --crf 28.00 --keyint -1 --rc 0 // --scd 0 --scm 0 --progress 3 // --color-primaries 9 --transfer-characteristics 16 // --matrix-coefficients 9 --color-range 1 // --chroma-sample-position 2 // --mastering-display "G(0.1700,0.7970)B(0.1310,0.0460)R(0.6800,0.3200)WP(0.3127,0.3290)L(1000.0000,0.0050)" // --content-light "1000,400" // --film-grain 24 --film-grain-denoise 0 // --lp 8 --preset 6 -b output.ivf ``` -------------------------------- ### Extract and Convert Video Frames (Rust) Source: https://context7.com/emrakyz/xav/llms.txt This snippet demonstrates how to extract video frames from a source, convert them between 8-bit and 10-bit formats, and pack/unpack 10-bit data efficiently. It utilizes the `ffms` library for video decoding and manipulation. Ensure `ffms` is correctly linked. ```rust use std::sync::Arc; let idx = ffms::VidIdx::new(&video_path, false)?; let inf = ffms::get_vidinf(&idx)?; // Create threaded video source for decoding let threads = 4; let vid_src = ffms::thr_vid_src(&idx, threads)?; // Extract 10-bit frame let frame_10bit_size = ffms::calc_10bit_size(&inf); let mut frame_10bit_buffer = vec![0u8; frame_10bit_size]; ffms::extr_10bit(vid_src, 0, &mut frame_10bit_buffer)?; // Pack 10-bit data to compressed format (4 pixels -> 5 bytes) let packed_size = ffms::calc_packed_size(&inf); let mut packed_buffer = vec![0u8; packed_size]; ffms::pack_10bit(&frame_10bit_buffer, &mut packed_buffer); // Later, unpack when needed let mut unpacked_buffer = vec![0u8; frame_10bit_size]; ffms::unpack_10bit(&packed_buffer, &mut unpacked_buffer); // For 8-bit sources, extract and convert to 10-bit let frame_8bit_size = ffms::calc_8bit_size(&inf); let mut frame_8bit_buffer = vec![0u8; frame_8bit_size]; ffms::extr_8bit(vid_src, 0, &mut frame_8bit_buffer)?; let mut converted_10bit = vec![0u8; frame_10bit_size]; ffms::conv_to_10bit(&frame_8bit_buffer, &mut converted_10bit); // Clean up ffms::destroy_vid_src(vid_src); ``` -------------------------------- ### Index Video and Extract Metadata (Rust) Source: https://context7.com/emrakyz/xav/llms.txt Creates a video index from a file path and extracts comprehensive video properties including resolution, frame rate, total frames, 10-bit status, and HDR metadata. This function is essential for preparing video data for subsequent processing. ```rust use std::path::Path; use std::sync::Arc; // Create a video index from file let video_path = Path::new("input.mkv"); let quiet_mode = false; let idx = ffms::VidIdx::new(&video_path, quiet_mode)?; // Extract video information let video_info = ffms::get_vidinf(&idx)?; println!("Resolution: {}x{}", video_info.width, video_info.height); println!("FPS: {}/{}", video_info.fps_num, video_info.fps_den); println!("Total frames: {}", video_info.frames); println!("10-bit source: {}", video_info.is_10bit); // Access HDR metadata if available if let Some(mastering_display) = &video_info.mastering_display { println!("Mastering Display: {}", mastering_display); } if let Some(content_light) = &video_info.content_light { println!("Content Light Level: {}", content_light); } // Color information if let Some(primaries) = video_info.color_primaries { println!("Color Primaries: {}", primaries); } if let Some(transfer) = video_info.transfer_characteristics { println!("Transfer Characteristics: {}", transfer); } ``` -------------------------------- ### Video Decode Strategies and Pipeline Configuration Source: https://context7.com/emrakyz/xav/llms.txt Selects optimized decode strategies based on video characteristics and cropping requirements. It initializes video index and information, determines the optimal decode strategy (considering 8-bit vs. 10-bit, cropping, and stride), and constructs a processing pipeline. The quality target can be optionally specified for specific features. ```rust use std::sync::Arc; let idx = ffms::VidIdx::new(&video_path, false)?; let inf = ffms::get_vidinf(&idx)?; // Crop values: (vertical, horizontal) let crop = (8, 0); // 8px top/bottom crop // Get optimal decode strategy let decode_strat = ffms::get_decode_strat(&idx, &inf, crop)?; // Available strategies (automatically selected): // - B10Fast, B10Stride: 10-bit sources without crop // - B10FastRem, B10StrideRem: 10-bit with width not divisible by 8 // - B10CropFast, B10Crop: 10-bit with cropping // - B10CropFastRem, B10CropRem: 10-bit crop with width remainder // - B10CropStride, B10CropStrideRem: 10-bit crop with stride optimization // - B8Fast, B8Stride: 8-bit sources // - B8CropFast, B8Crop, B8CropStride: 8-bit with cropping // Create pipeline with decode strategy #[cfg(feature = "vship")] let target_quality = Some("82.0-84.0"); // SSIMULACRA2 range #[cfg(not(feature = "vship"))] let target_quality = None; let pipeline = pipeline::Pipeline::new(&inf, decode_strat, target_quality); println!("Final resolution: {}x{}\n", pipeline.final_w, pipeline.final_h); println!("Frame size: {} bytes\n", pipeline.frame_size); println!("Conversion buffer: {} bytes\n", pipeline.conv_buf_size); ``` -------------------------------- ### Target Quality Encoding with VSHIP (Rust) Source: https://context7.com/emrakyz/xav/llms.txt This snippet configures and demonstrates target quality encoding using the VSHIP feature, which is enabled via a Cargo feature flag. It outlines the structure for setting target quality ranges, metric aggregation modes, and interpolation methods for iterative probing. ```rust #[cfg(feature = "vship")] { use std::path::PathBuf; // Configure target quality encoding let args = Args { worker: 8, scene_file: PathBuf::from("scenes.txt"), target_quality: Some("82.0-84.0".to_string()), // SSIMULACRA2 range metric_mode: "mean".to_string(), // or "p0.1" for percentile qp_range: Some("8.0-48.0".to_string()), metric_worker: 3, params: "--lp 8 --preset 6".to_string(), resume: false, quiet: false, noise: None, audio: None, input: PathBuf::from("input.mkv"), output: PathBuf::from("output.mkv"), decode_strat: None, chunk_buffer: 8, }; // Metric ranges: // < 8.0: Butteraugli (5-Percentile Norm, lower is better) // 8-10: CVVDP (cumulative metric, lower is better) // > 10: SSIMULACRA2 (perceptual quality, higher is better) // Aggregation modes: // "mean": Average of all frame scores // "p0.1": Mean of worst 0.1% of frames // "p1": Mean of worst 1% of frames // "p5": Mean of worst 5% of frames // Interpolation methods (automatic based on probe count): // Round 1-2: Binary search // Round 3: Linear interpolation (2 probes) // Round 4: Natural cubic spline (3+ probes) // Round 5: PCHIP (4 probes) // Round 6+: Akima spline (5 probes) // Command line usage: // xav -t "82.0-84.0" -m "mean" input.mkv // xav -t "6.5-7.0" -m "p0.1" input.mkv (Butteraugli) // xav -t "8.5-9.0" -f "12.0-38.0" input.mkv (CVVDP with custom CRF range) } ``` -------------------------------- ### Rust Resume Functionality for Interrupted Encoding Sessions Source: https://context7.com/emrakyz/xav/llms.txt Enables saving and restoring encoding state for interrupted sessions. It tracks chunk completion data, saves resume information to a specified directory, and allows for restoring this state later. The command-line option '-r' can be used to automatically restore all arguments from the temporary directory. ```rust use std::path::Path; use chunk::{ChunkComp, ResumeInf, get_resume, save_resume}; // During encoding, completion data is tracked let chunk_completion = ChunkComp { idx: 0, frames: 142, size: 524288, }; let work_dir = Path::new(".abc1234"); let mut resume_data = ResumeInf { chnks_done: vec![chunk_completion], }; // Save resume state save_resume(&resume_data, work_dir)?; // Later, restore the session if let Some(restored) = get_resume(work_dir) { println!("Found {} completed chunks", restored.chnks_done.len()); for chunk in restored.chnks_done { println!("Chunk {}: {} frames, {} bytes", chunk.idx, chunk.frames, chunk.size); } } // Resume from command line: // xav -r input.mkv // All arguments are restored from the temporary directory ``` -------------------------------- ### Rust Parallel Encoding Pipeline with Lockless MPSC Channels Source: https://context7.com/emrakyz/xav/llms.txt Implements a parallel chunked encoding pipeline using a lockless producer-consumer architecture. It sets up encoding configuration, detects crops, loads scenes, creates chunks, generates grain tables, and runs parallel encoding with multiple worker threads coordinated via MPSC channels. Finally, it merges encoded chunks and cleans up temporary files. Dependencies include 'ffms', 'crop', 'chunk', 'noise', and 'svt' crates. ```rust use std::path::{Path, PathBuf}; use std::sync::Arc; // Setup encoding configuration let args = Args { worker: 8, scene_file: PathBuf::from("scenes.txt"), #[cfg(feature = "vship")] target_quality: None, #[cfg(feature = "vship")] metric_mode: "mean".to_string(), #[cfg(feature = "vship")] qp_range: None, #[cfg(feature = "vship")] metric_worker: 3, params: "--lp 8 --preset 6 --crf 28".to_string(), resume: false, quiet: false, noise: Some(800), // ISO 800 grain audio: None, input: PathBuf::from("input.mkv"), output: PathBuf::from("output.mkv"), decode_strat: None, chunk_buffer: 8, }; // Create index and extract info let idx = ffms::VidIdx::new(&args.input, args.quiet)?; let inf = ffms::get_vidinf(&idx)?; // Detect crop let config = crop::CropDetectConfig { sample_count: 13, min_black_pixels: 2 }; let crop = match crop::detect_crop(&idx, &inf, &config) { Ok(detected) if detected.has_crop() => detected.to_tuple(), _ => (0, 0), }; // Get decode strategy let decode_strat = ffms::get_decode_strat(&idx, &inf, crop)?; // Load scenes and create chunks let scenes = chunk::load_scenes(&args.scene_file, inf.frames)?; chunk::validate_scenes(&scenes, inf.fps_num, inf.fps_den)?; let chunks = chunk::chunkify(&scenes); // Create working directory let hash = hash_input(&args.input); let work_dir = PathBuf::from(format!(".{}", &hash[..7])); std::fs::create_dir_all(work_dir.join("split"))?; std::fs::create_dir_all(work_dir.join("encode"))?; // Generate grain table if requested let grain_table = if let Some(iso) = args.noise { let table_path = work_dir.join("grain.tbl"); noise::gen_table(iso, &inf, &table_path)?; Some(table_path) } else { None }; // Run parallel encoding // - Single decoder thread extracts frames // - Multiple encoder workers process chunks in parallel // - Lockless MPSC channels coordinate work // - Bounded channels prevent memory explosion svt::encode_all(&chunks, &inf, &args, &idx, &work_dir, grain_table.as_ref()); // Merge encoded chunks chunk::merge_out( &work_dir.join("encode"), &args.output, &inf, Some(&args.input) // Include audio/subtitles from source )?; // Cleanup std::fs::remove_dir_all(&work_dir)?; ``` -------------------------------- ### Rust Interpolation Functions: Linear, Cubic Spline, PCHIP, Akima Source: https://context7.com/emrakyz/xav/llms.txt Provides mathematical interpolation utilities for target quality calculations. Supports linear, natural cubic spline, PCHIP, and Akima spline interpolations. Uses the 'interp' crate. Input requires x and y coordinates and the point of interpolation. Output is the interpolated value. ```rust use interp::{lerp, natural_cubic, pchip, akima}; // Linear interpolation (2 points) let x_linear = [70.0, 75.0]; let y_linear = [25.0, 30.0]; let result = lerp(&x_linear, &y_linear, 72.5)?; println!("Linear interpolation at 72.5: {}", result); // ~27.5 // Natural cubic spline (3+ points) let x_cubic = vec![70.0, 72.0, 74.0, 76.0, 78.0]; let y_cubic = vec![25.0, 26.5, 28.0, 29.0, 30.5]; let result = natural_cubic(&x_cubic, &y_cubic, 75.0)?; // PCHIP (Piecewise Cubic Hermite Interpolating Polynomial) - 4 points let x_pchip = [70.0, 72.0, 74.0, 76.0]; let y_pchip = [25.0, 26.5, 28.0, 29.0]; let result = pchip(&x_pchip, &y_pchip, 73.0)?; // Akima spline - 5 points let x_akima = [70.0, 72.0, 74.0, 76.0, 78.0]; let y_akima = [25.0, 26.5, 28.0, 29.0, 30.5]; let result = akima(&x_akima, &y_akima, 75.5)?; ``` -------------------------------- ### Audio Encoding with Opus Source: https://context7.com/emrakyz/xav/llms.txt Encodes audio streams to Opus format, supporting automatic or manual bitrate selection. It parses audio specifications, processes audio after video encoding, and allows for different bitrate modes including auto, normalized, and fixed. ```rust use std::path::Path; // Parse audio specification let audio_spec = audio::parse_audio_arg("auto all")?; // Other examples: // "norm all" - Normalize all audio streams // "128 1" - 128 kbps for stream 1 // "auto 1,2" - Auto bitrate for streams 1 and 2 // Audio processing happens after video encoding let input = Path::new("input.mkv"); let video_mkv = Path::new("video_only.mkv"); let output = Path::new("final.mkv"); audio::process_audio(&audio_spec, &input, &video_mkv, &output)?; // Bitrate modes: // - Auto: Calculated based on channel count (64k/ch for <=2ch, 45k/ch for >2ch) // - Norm: Normalized to -14 LUFS with loudnorm filter // - Fixed: Specific bitrate per stream (e.g., 128 kbps) // Command line usage: // xav -a "auto all" input.mkv output.mkv // xav -a "norm 1" input.mkv output.mkv // xav -a "192 1,2" input.mkv output.mkv ``` -------------------------------- ### Film Grain Synthesis using Photon Noise Source: https://context7.com/emrakyz/xav/llms.txt Generates photon noise grain tables for authentic film-like quality. It takes an ISO value and video information to create a grain table, which is automatically applied during encoding. Supports both SDR and HDR transfer functions. ```rust use std::path::Path; let idx = ffms::VidIdx::new(&video_path, false)?; let inf = ffms::get_vidinf(&idx)?; // ISO values from 100 to 6400 (passed as 1-64, multiplied by 100) let iso = 800; // ISO 800 let grain_table_path = Path::new("grain.tbl"); // Generate grain table with automatic transfer function detection noise::gen_table(iso, &inf, &grain_table_path)?; // The grain table is automatically applied during encoding // Supports both SDR (BT.1886) and HDR (PQ/SMPTE 2084) transfer functions // Command line usage: // xav -n 8 input.mkv output.mkv (ISO 800) // xav -n 32 input.mkv output.mkv (ISO 3200) ``` -------------------------------- ### Scene Change Detection and Chunking Source: https://context7.com/emrakyz/xav/llms.txt Detects scene changes in videos and prepares them for chunked encoding. It automatically calculates minimum and maximum distances for scene detection based on framerate and generates a scene list. The detected scenes are then validated and converted into chunks for processing. ```rust use std::path::Path; // Run scene change detection let input_path = Path::new("video.mkv"); let scene_output = Path::new("scenes.txt"); let quiet = false; // Automatically calculates: // min_dist = (fps_num + fps_den / 2) / fps_den (1 second) // max_dist = min(((fps_num * 10 + fps_den / 2) / fps_den), 300) (10 seconds or 300 frames) scd::fd_scenes(&input_path, &scene_output, quiet)?; // The scene file contains frame numbers (one per line): // 0 // 142 // 289 // 512 // ... // Load scene file for processing let idx = ffms::VidIdx::new(&input_path, false)?; let inf = ffms::get_vidinf(&idx)?; let scenes = chunk::load_scenes(&scene_output, inf.frames)?; // Validate scene durations chunk::validate_scenes(&scenes, inf.fps_num, inf.fps_den)?; // Convert scenes to chunks for encoding let chunks = chunk::chunkify(&scenes); for chunk in &chunks { println!("Chunk {}: frames {} to {}\n", chunk.idx, chunk.start, chunk.end); } ``` -------------------------------- ### Detect Black Bar Crop (Rust) Source: https://context7.com/emrakyz/xav/llms.txt Automatically detects and calculates crop values for removing black bars from video frames. It uses a configurable sampling strategy and provides results in both raw and symmetric crop formats, indicating the final resolution after cropping. ```rust use std::path::Path; use std::sync::Arc; let idx = ffms::VidIdx::new(&video_path, false)?; let inf = ffms::get_vidinf(&idx)?; // Configure crop detection let config = crop::CropDetectConfig { sample_count: 13, // Number of frames to sample min_black_pixels: 2, // Black threshold tolerance }; // Detect crop values let crop_result = crop::detect_crop(&idx, &inf, &config)?; if crop_result.has_crop() { println!("Detected crop: top={}, bottom={}, left={}, right={}", crop_result.top, crop_result.bottom, crop_result.left, crop_result.right); // Convert to symmetric crop tuple (vertical, horizontal) let (crop_v, crop_h) = crop_result.to_tuple(); println!("Symmetric crop: {}px vertical, {}px horizontal", crop_v, crop_h); let final_width = inf.width - crop_h * 2; let final_height = inf.height - crop_v * 2; println!("Final resolution: {}x{}", final_width, final_height); } // Crop detection is automatic in the encoding pipeline // The detected values are applied to all decode strategies ``` -------------------------------- ### Merge Encoded Chunks with mkvmerge (Rust) Source: https://context7.com/emrakyz/xav/llms.txt Concatenates encoded video chunks (e.g., .ivf files) into a final MKV output file using mkvmerge. This function can optionally include audio and subtitles from a source file and sets the correct framerate metadata. ```rust use std::path::Path; use std::process::Command; let encode_dir = Path::new(".abc1234/encode"); let output = Path::new("final_output.mkv"); let input = Path::new("source.mkv"); // Merges all .ivf files in numerical order (0000.ivf, 0001.ivf, ...) // Sets proper framerate metadata // Optionally includes audio, subtitles from source chunk::merge_out(&encode_dir, &output, &inf, Some(&input))?; // If audio is being encoded separately: let video_only = Path::new("video.mkv"); chunk::merge_out(&encode_dir, &video_only, &inf, None)?; // Equivalent mkvmerge command for video-only: // mkvmerge -q -o output.mkv -A -S -B -M -T --no-global-tags // --no-chapters --no-date --disable-language-ietf // 0000.ivf + 0001.ivf + 0002.ivf ... // --default-duration 0:24000/1001fps // With source audio/subs: // mkvmerge -q -o output.mkv -D -B source.mkv ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.