143 lines
5.0 KiB
C++
143 lines
5.0 KiB
C++
#pragma once
|
|
#include "NVDECAV1Decoder.h"
|
|
#include <queue>
|
|
#include <mutex>
|
|
#include <atomic>
|
|
|
|
namespace VavCore {
|
|
|
|
// Performance monitoring data
|
|
struct PerformanceMetrics {
|
|
double avg_decode_time_ms = 0.0;
|
|
double avg_render_time_ms = 0.0;
|
|
double cpu_usage_percent = 0.0;
|
|
double gpu_usage_percent = 0.0;
|
|
uint64_t dropped_frames = 0;
|
|
std::chrono::steady_clock::time_point last_update;
|
|
};
|
|
|
|
// Quality levels for adaptive adjustment
|
|
enum class QualityLevel {
|
|
ULTRA = 0, // Original resolution, full quality
|
|
HIGH = 1, // 75% resolution, high quality
|
|
MEDIUM = 2, // 50% resolution, medium quality
|
|
LOW = 3, // 25% resolution, low quality
|
|
MINIMUM = 4 // 12.5% resolution, minimal quality
|
|
};
|
|
|
|
// Adaptive decoder configuration
|
|
struct AdaptiveConfig {
|
|
// Performance thresholds (milliseconds)
|
|
double target_frame_time_ms = 33.33; // 30 FPS target
|
|
double critical_frame_time_ms = 50.0; // 20 FPS critical
|
|
|
|
// Quality adjustment thresholds
|
|
double quality_up_threshold = 0.8; // Scale up when < 80% of target time
|
|
double quality_down_threshold = 1.2; // Scale down when > 120% of target time
|
|
|
|
// Hysteresis to prevent oscillation
|
|
uint32_t stable_frames_required = 30; // Frames to wait before adjustment
|
|
|
|
// Memory constraints
|
|
uint32_t max_decode_surfaces = 16;
|
|
uint32_t min_decode_surfaces = 4;
|
|
|
|
// Enable/disable features
|
|
bool enable_dynamic_resolution = true;
|
|
bool enable_dynamic_surfaces = true;
|
|
bool enable_skip_non_reference = true;
|
|
};
|
|
|
|
// Enhanced NVDEC decoder with adaptive quality adjustment
|
|
class AdaptiveNVDECDecoder : public NVDECAV1Decoder {
|
|
public:
|
|
AdaptiveNVDECDecoder();
|
|
~AdaptiveNVDECDecoder() override;
|
|
|
|
// Enhanced initialization with adaptive features
|
|
bool Initialize(const VideoMetadata& metadata) override;
|
|
bool Initialize(const VideoMetadata& metadata, const AdaptiveConfig& config);
|
|
|
|
// Override decode with adaptive logic
|
|
bool DecodeFrame(const uint8_t* packet_data, size_t packet_size, VideoFrame& output_frame) override;
|
|
|
|
// Adaptive quality control
|
|
void SetQualityLevel(QualityLevel level);
|
|
QualityLevel GetCurrentQualityLevel() const { return m_currentQuality; }
|
|
|
|
// Performance monitoring
|
|
PerformanceMetrics GetPerformanceMetrics() const;
|
|
void UpdatePerformanceMetrics(double decode_time, double render_time);
|
|
|
|
// Manual override controls
|
|
void EnableAdaptiveMode(bool enable) { m_adaptiveEnabled = enable; }
|
|
void SetTargetFrameRate(double fps);
|
|
void ForceQualityAdjustment(); // Immediate adjustment trigger
|
|
|
|
// Configuration management
|
|
void UpdateConfig(const AdaptiveConfig& config) { m_config = config; }
|
|
AdaptiveConfig GetConfig() const { return m_config; }
|
|
|
|
private:
|
|
// Adaptive control state
|
|
QualityLevel m_currentQuality = QualityLevel::ULTRA;
|
|
QualityLevel m_targetQuality = QualityLevel::ULTRA;
|
|
AdaptiveConfig m_config;
|
|
|
|
// Performance monitoring
|
|
mutable std::mutex m_metricsMutex;
|
|
PerformanceMetrics m_metrics;
|
|
std::queue<double> m_recentDecodeTimes;
|
|
std::queue<double> m_recentRenderTimes;
|
|
|
|
// Adaptive decision making
|
|
std::atomic<bool> m_adaptiveEnabled{true};
|
|
uint32_t m_stableFrameCount = 0;
|
|
bool m_needsReconfiguration = false;
|
|
|
|
// Original video properties for scaling calculations
|
|
uint32_t m_originalWidth = 0;
|
|
uint32_t m_originalHeight = 0;
|
|
|
|
// Current scaled properties
|
|
uint32_t m_currentScaledWidth = 0;
|
|
uint32_t m_currentScaledHeight = 0;
|
|
|
|
// Adaptive logic methods
|
|
void AnalyzePerformanceAndAdjust();
|
|
bool ShouldAdjustQuality(double avgDecodeTime, double avgRenderTime);
|
|
QualityLevel DetermineOptimalQuality(double totalFrameTime);
|
|
|
|
// NVDEC reconfiguration methods
|
|
bool ReconfigureDecoder(uint32_t newWidth, uint32_t newHeight);
|
|
bool UpdateDecodeSurfaces(uint32_t newCount);
|
|
void CalculateScaledDimensions(QualityLevel quality, uint32_t& width, uint32_t& height);
|
|
|
|
// Performance calculation helpers
|
|
void UpdateMovingAverage(std::queue<double>& queue, double newValue, size_t maxSize = 30);
|
|
double CalculateMovingAverage(const std::queue<double>& queue) const;
|
|
|
|
// Quality level utilities
|
|
static double GetQualityScaleFactor(QualityLevel level);
|
|
static std::string QualityLevelToString(QualityLevel level);
|
|
};
|
|
|
|
// Utility functions for adaptive decoding
|
|
namespace AdaptiveUtils {
|
|
// Performance estimation
|
|
double EstimateOptimalFrameRate(const PerformanceMetrics& metrics);
|
|
QualityLevel RecommendQualityForTargetFPS(double targetFPS, double currentFPS);
|
|
|
|
// System resource monitoring
|
|
double GetCurrentCPUUsage();
|
|
double GetCurrentGPUUsage();
|
|
size_t GetAvailableGPUMemory();
|
|
|
|
// Configuration presets
|
|
AdaptiveConfig CreateConfigForTarget(double targetFPS);
|
|
AdaptiveConfig GetConservativeConfig(); // Aggressive quality reduction
|
|
AdaptiveConfig GetBalancedConfig(); // Balanced performance/quality
|
|
AdaptiveConfig GetQualityConfig(); // Prioritize quality over performance
|
|
}
|
|
|
|
} // namespace VavCore
|