feat: 完成 tvai 库便捷接口和优化 (阶段五)

全局配置管理系统
- 实现 GlobalSettings 全局设置结构
- 实现 SettingsManager 设置管理器
- 支持配置文件持久化 (TOML 格式)
- 自动检测用户配置目录
- 全局设置单例模式访问

 预设管理系统
- 实现 VideoPreset 和 ImagePreset 预设结构
- 实现 PresetManager 预设管理器
- 内置 8 种视频处理预设
- 内置 6 种图片处理预设
- 支持自定义预设添加和管理

 高级 GPU 检测和优化
- 实现 GpuManager 详细 GPU 检测
- 支持 CUDA、OpenCL、Vulkan 检测
- 详细的 GPU 设备信息获取
- 智能推荐设置生成
- GPU 性能基准测试功能

 性能监控和优化
- 实现 PerformanceMonitor 性能监控器
- 支持并发控制和资源管理
- 详细的性能指标收集
- 智能性能建议生成
- 系统优化参数自动调整

 增强错误处理系统
- 扩展 TvaiError 错误类型 (12 种错误)
- 用户友好的错误信息和建议
- 错误分类和可恢复性判断
- 详细的故障排除指导
- 错误上下文和解决方案

 便捷工具函数
- optimize_for_system() 系统优化
- 全局设置和预设访问函数
- GPU 适用性检查函数
- 性能基准测试工具
- 智能参数推荐系统

 配置文件支持
- TOML 格式配置文件
- 自动配置目录检测
- 设置持久化和加载
- 配置验证和错误处理
- 跨平台配置管理

 完整示例和演示
- 创建 convenience_and_optimization.rs 综合示例
- 全局设置管理演示
- 预设管理系统演示
- GPU 优化和检测演示
- 性能监控和基准测试演示
- 增强错误处理演示

 技术特性
- 全局状态管理和配置持久化
- 智能系统检测和优化建议
- 详细的性能监控和分析
- 用户友好的错误处理和恢复
- 跨平台兼容性和配置管理

 代码质量
- 所有测试通过 (6/6 单元测试 + 1 文档测试)
- 完整的错误处理和用户指导
- 内存安全的资源管理
- 清晰的 API 设计和文档

 功能覆盖
-  全局配置管理 (设置持久化)
-  预设管理系统 (14 种内置预设)
-  高级 GPU 检测 (CUDA/OpenCL/Vulkan)
-  性能监控优化 (并发控制/资源管理)
-  增强错误处理 (12 种错误类型)
-  便捷工具函数 (系统优化/智能推荐)

 新增依赖
- toml v0.8 (配置文件支持)
- dirs v5.0 (用户目录检测)

项目完成度: 100% - 所有核心功能已实现并测试通过
This commit is contained in:
imeepos
2025-08-11 16:03:27 +08:00
parent af41779220
commit a692741d82
11 changed files with 1359 additions and 10 deletions

View File

@@ -0,0 +1,231 @@
//! Convenience interfaces and optimization examples
use tvai::*;
use tvai::config::{global_settings, global_presets};
use tvai::utils::{GpuManager, PerformanceMonitor, optimize_for_system};
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Topaz Video AI Library - Convenience and Optimization Examples");
// Demonstrate global settings management
demonstrate_global_settings().await?;
// Demonstrate preset management
demonstrate_preset_management().await?;
// Demonstrate GPU detection and optimization
demonstrate_gpu_optimization().await?;
// Demonstrate performance monitoring
demonstrate_performance_monitoring().await?;
// Demonstrate error handling
demonstrate_error_handling().await?;
println!("All convenience and optimization examples completed successfully!");
Ok(())
}
async fn demonstrate_global_settings() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Global Settings Management Demo ===");
// Get global settings manager
let settings_manager = global_settings();
// Display current settings
let current_settings = settings_manager.get_settings();
println!("Current Settings:");
println!(" Default GPU usage: {}", current_settings.default_use_gpu);
println!(" Max concurrent jobs: {}", current_settings.max_concurrent_jobs);
println!(" Auto-detect Topaz: {}", current_settings.auto_detect_topaz);
println!(" Verbose logging: {}", current_settings.verbose_logging);
// Update settings
settings_manager.set_default_use_gpu(true)?;
settings_manager.set_max_concurrent_jobs(2)?;
println!("Updated settings successfully");
// Create config from global settings
match settings_manager.create_config() {
Ok(_config) => println!("Successfully created config from global settings"),
Err(e) => println!("Config creation failed (expected): {}", e.user_friendly_message()),
}
Ok(())
}
async fn demonstrate_preset_management() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Preset Management Demo ===");
// Get global preset manager
let presets = global_presets();
let preset_manager = presets.lock().unwrap();
// List available video presets
println!("Available Video Presets:");
for preset_name in preset_manager.list_video_presets() {
if let Some(preset) = preset_manager.get_video_preset(&preset_name) {
println!(" {}: {}", preset.name, preset.description);
}
}
// List available image presets
println!("\nAvailable Image Presets:");
for preset_name in preset_manager.list_image_presets() {
if let Some(preset) = preset_manager.get_image_preset(&preset_name) {
println!(" {}: {}", preset.name, preset.description);
}
}
// Demonstrate using a preset
if let Some(preset) = preset_manager.get_video_preset("general_2x") {
println!("\nUsing preset: {}", preset.name);
if let Some(ref upscale) = preset.upscale {
println!(" Upscale model: {}", upscale.model.as_str());
println!(" Scale factor: {}x", upscale.scale_factor);
}
}
Ok(())
}
async fn demonstrate_gpu_optimization() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== GPU Optimization Demo ===");
// Detect detailed GPU information
let gpu_info = GpuManager::detect_detailed_gpu_info();
println!("GPU Detection Results:");
println!(" Available: {}", gpu_info.available);
println!(" CUDA: {}", gpu_info.cuda_available);
println!(" OpenCL: {}", gpu_info.opencl_available);
println!(" Vulkan: {}", gpu_info.vulkan_available);
// Display detected devices
println!("\nDetected GPU Devices:");
for (idx, device) in gpu_info.devices.iter().enumerate() {
println!(" Device {}: {}", idx, device.name);
println!(" Vendor: {}", device.vendor);
if let Some(memory) = device.memory_mb {
println!(" Memory: {} MB", memory);
}
println!(" AI Support: {}", device.supports_ai);
}
// Display recommendations
println!("\nRecommended Settings:");
println!(" Use GPU: {}", gpu_info.recommended_settings.use_gpu);
if let Some(device_idx) = gpu_info.recommended_settings.preferred_device {
println!(" Preferred device: {}", device_idx);
}
if let Some(memory_limit) = gpu_info.recommended_settings.memory_limit_mb {
println!(" Memory limit: {} MB", memory_limit);
}
println!(" Concurrent streams: {}", gpu_info.recommended_settings.concurrent_streams);
// Check if GPU is suitable for AI
let suitable = GpuManager::is_gpu_suitable_for_ai();
println!("\nGPU suitable for AI workloads: {}", suitable);
// Benchmark GPU performance
println!("\nRunning GPU benchmark...");
match GpuManager::benchmark_gpu_performance().await {
Ok(benchmark) => {
println!("Benchmark Results:");
println!(" Processing time: {:?}", benchmark.processing_time);
println!(" Memory bandwidth: {:.1} GB/s", benchmark.memory_bandwidth_gbps);
println!(" Compute score: {}", benchmark.compute_score);
println!(" Recommended for AI: {}", benchmark.recommended_for_ai);
}
Err(e) => println!("Benchmark failed: {}", e),
}
Ok(())
}
async fn demonstrate_performance_monitoring() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Performance Monitoring Demo ===");
// Create optimized performance settings
let settings = optimize_for_system();
println!("Optimized Performance Settings:");
println!(" Max concurrent ops: {}", settings.max_concurrent_ops);
println!(" Processing mode: {:?}", settings.processing_mode);
println!(" Chunk size: {} MB", settings.chunk_size_mb);
println!(" Monitoring enabled: {}", settings.enable_monitoring);
// Create performance monitor
let mut monitor = PerformanceMonitor::new(settings);
// Simulate a processing operation
println!("\nSimulating processing operation...");
let metrics = {
let _permit = monitor.acquire_slot().await?;
let operation_monitor = monitor.start_operation("video_upscale", 100.0);
// Simulate processing time
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
// Finish monitoring
operation_monitor.finish(200.0)
};
// Record metrics after permit is dropped
monitor.record_metrics(metrics.clone());
println!("Operation completed:");
println!(" Input size: {:.1} MB", metrics.input_size_mb);
println!(" Output size: {:.1} MB", metrics.output_size_mb);
println!(" Processing time: {:?}", metrics.processing_time);
println!(" Throughput: {:.2} MB/s", metrics.throughput_mbps);
// Get performance summary
let summary = monitor.get_summary();
println!("\nPerformance Summary:");
println!(" Total operations: {}", summary.total_operations);
println!(" Average throughput: {:.2} MB/s", summary.average_throughput_mbps);
if !summary.recommendations.is_empty() {
println!(" Recommendations:");
for rec in summary.recommendations {
println!("{}", rec);
}
}
Ok(())
}
async fn demonstrate_error_handling() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Enhanced Error Handling Demo ===");
// Demonstrate different error types and their user-friendly messages
let errors = vec![
TvaiError::TopazNotFound("/invalid/path".to_string()),
TvaiError::FfmpegError("Invalid codec".to_string()),
TvaiError::InvalidParameter("Scale factor out of range".to_string()),
TvaiError::GpuError("CUDA out of memory".to_string()),
TvaiError::UnsupportedFormat("WEBM".to_string()),
TvaiError::InsufficientResources("Not enough memory".to_string()),
TvaiError::PermissionDenied("Cannot write to output directory".to_string()),
];
for error in errors {
println!("\nError Type: {}", error.category());
println!("Recoverable: {}", error.is_recoverable());
println!("User-friendly message:");
println!("{}", error.user_friendly_message());
println!("{}", "-".repeat(50));
}
Ok(())
}
// Helper function to create a progress callback
fn create_progress_callback(operation_name: &str) -> ProgressCallback {
let name = operation_name.to_string();
Box::new(move |progress| {
let percentage = (progress * 100.0) as u32;
println!("{}: {}%", name, percentage);
})
}