Ahmad Ayad commited on
added zero total score for very low compressed videos (#91)
Browse files
services/scoring/scoring_function.py
CHANGED
|
@@ -42,6 +42,16 @@ def calculate_compression_score(
|
|
| 42 |
# Calculate hard cutoff point
|
| 43 |
hard_cutoff = vmaf_threshold - soft_threshold_margin
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
# ========================================================================
|
| 46 |
# CASE 1: Below Hard Cutoff - Immediate Failure
|
| 47 |
# ========================================================================
|
|
@@ -72,48 +82,44 @@ def calculate_compression_score(
|
|
| 72 |
"""
|
| 73 |
quality_factor = 0.7 * (soft_zone_position ** 2)
|
| 74 |
|
| 75 |
-
# Calculate compression component
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
else:
|
| 80 |
-
|
|
|
|
|
|
|
| 81 |
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
Where r is compression ratio (e.g., 5 for 5x compression)
|
| 88 |
-
- At 1x: component = 0
|
| 89 |
-
- At 2x: component β 0.23
|
| 90 |
-
- At 5x: component β 0.65
|
| 91 |
-
- At 10x: component β 0.89
|
| 92 |
-
- At 15x: component β 0.97
|
| 93 |
-
- At 20x: component = 1.0
|
| 94 |
-
|
| 95 |
-
The exponent 1.5 provides:
|
| 96 |
-
- Slow growth initially (encouraging minimum viable compression)
|
| 97 |
-
- Steeper growth in practical range (5-15x)
|
| 98 |
-
- Reaches 1.0 exactly at 20x
|
| 99 |
-
"""
|
| 100 |
-
compression_component = ((compression_ratio - 1) / 19) ** 1.5
|
| 101 |
-
else:
|
| 102 |
-
"""
|
| 103 |
-
Bonus for exceptional compression (>20x):
|
| 104 |
-
f(r) = 1.0 + 0.3 * ln(r / 20)
|
| 105 |
-
|
| 106 |
-
Logarithmic bonus rewards exceptional performance:
|
| 107 |
-
- At 20x: component = 1.0 (continuous at boundary)
|
| 108 |
-
- At 30x: component β 1.12
|
| 109 |
-
- At 40x: component β 1.21
|
| 110 |
-
- At 60x: component β 1.30 (capped)
|
| 111 |
-
|
| 112 |
-
Natural log ensures smooth transition from linear region.
|
| 113 |
-
"""
|
| 114 |
-
compression_component = 1.0 + 0.3 * math.log(compression_ratio / 20)
|
| 115 |
|
| 116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
# In soft zone, both compression AND quality factor matter
|
| 119 |
# If you're below threshold, you need good compression to recover
|
|
@@ -150,66 +156,42 @@ def calculate_compression_score(
|
|
| 150 |
"""
|
| 151 |
quality_component = 0.7 + 0.3 * min(1.0, vmaf_excess / max_vmaf_excess)
|
| 152 |
|
| 153 |
-
# Calculate compression component
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
reason_suffix = " (WARNING: minimal compression)"
|
| 158 |
-
|
| 159 |
-
elif compression_rate >= 0.80:
|
| 160 |
"""
|
| 161 |
-
|
| 162 |
-
f(r) = ((r - 1)
|
| 163 |
|
| 164 |
-
|
| 165 |
-
- At 1.
|
| 166 |
-
- At
|
| 167 |
-
- At
|
| 168 |
-
-
|
|
|
|
|
|
|
| 169 |
|
| 170 |
-
|
| 171 |
"""
|
| 172 |
-
|
| 173 |
-
compression_component = (compression_ratio - 1) ** 2 * 0.4
|
| 174 |
-
reason_suffix = " (poor compression)"
|
| 175 |
-
|
| 176 |
else:
|
| 177 |
-
|
| 178 |
-
|
|
|
|
| 179 |
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
Starting from 1.25x to give smooth transition from poor zone:
|
| 186 |
-
- At 1.25x: component = 0.025
|
| 187 |
-
- At 2x: component β 0.24
|
| 188 |
-
- At 5x: component β 0.64
|
| 189 |
-
- At 10x: component β 0.88
|
| 190 |
-
- At 15x: component β 0.96
|
| 191 |
-
- At 20x: component = 1.0
|
| 192 |
-
|
| 193 |
-
The exponent 1.2 provides balanced reward curve.
|
| 194 |
-
"""
|
| 195 |
-
compression_component = ((compression_ratio - 1.25) / 18.75) ** 1.2 + 0.025
|
| 196 |
-
else:
|
| 197 |
-
"""
|
| 198 |
-
Exceptional compression bonus (>20x):
|
| 199 |
-
f(r) = 1.0 + 0.3 * ln(r / 20)
|
| 200 |
-
|
| 201 |
-
Logarithmic bonus up to 1.3 cap:
|
| 202 |
-
- At 20x: component = 1.0 (continuous at boundary)
|
| 203 |
-
- At 30x: component β 1.12
|
| 204 |
-
- At 40x: component β 1.21
|
| 205 |
-
- At 60x: component β 1.30 (capped)
|
| 206 |
-
|
| 207 |
-
Natural log ensures smooth transition from power region.
|
| 208 |
-
"""
|
| 209 |
-
compression_component = 1.0 + 0.3 * math.log(compression_ratio / 20)
|
| 210 |
|
| 211 |
-
|
| 212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
|
| 214 |
"""
|
| 215 |
Final score is weighted combination:
|
|
|
|
| 42 |
# Calculate hard cutoff point
|
| 43 |
hard_cutoff = vmaf_threshold - soft_threshold_margin
|
| 44 |
|
| 45 |
+
# ========================================================================
|
| 46 |
+
# CASE 0: No Meaningful Compression - Immediate Failure
|
| 47 |
+
# ========================================================================
|
| 48 |
+
# If compression_rate >= 0.80 (less than 1.25x compression), this is likely
|
| 49 |
+
# the miner returning the same video or minimal compression to exploit high VMAF.
|
| 50 |
+
# Zero the entire score to prevent this exploit.
|
| 51 |
+
if compression_rate >= 0.80:
|
| 52 |
+
compression_ratio = 1 / compression_rate if compression_rate > 0 else 1.0
|
| 53 |
+
return 0.0, 0.0, 0.0, f"No meaningful compression (ratio: {compression_ratio:.2f}x, rate: {compression_rate:.2f}). Minimum 1.25x required."
|
| 54 |
+
|
| 55 |
# ========================================================================
|
| 56 |
# CASE 1: Below Hard Cutoff - Immediate Failure
|
| 57 |
# ========================================================================
|
|
|
|
| 82 |
"""
|
| 83 |
quality_factor = 0.7 * (soft_zone_position ** 2)
|
| 84 |
|
| 85 |
+
# Calculate compression component (compression_rate < 0.80 guaranteed by CASE 0)
|
| 86 |
+
compression_ratio = 1 / compression_rate
|
| 87 |
+
|
| 88 |
+
if compression_ratio <= 20:
|
| 89 |
+
"""
|
| 90 |
+
Compression scoring for 1x to 20x:
|
| 91 |
+
f(r) = ((r - 1) / 19) ^ 1.5
|
| 92 |
+
|
| 93 |
+
Where r is compression ratio (e.g., 5 for 5x compression)
|
| 94 |
+
- At 1x: component = 0
|
| 95 |
+
- At 2x: component β 0.23
|
| 96 |
+
- At 5x: component β 0.65
|
| 97 |
+
- At 10x: component β 0.89
|
| 98 |
+
- At 15x: component β 0.97
|
| 99 |
+
- At 20x: component = 1.0
|
| 100 |
+
|
| 101 |
+
The exponent 1.5 provides:
|
| 102 |
+
- Slow growth initially (encouraging minimum viable compression)
|
| 103 |
+
- Steeper growth in practical range (5-15x)
|
| 104 |
+
- Reaches 1.0 exactly at 20x
|
| 105 |
+
"""
|
| 106 |
+
compression_component = ((compression_ratio - 1) / 19) ** 1.5
|
| 107 |
else:
|
| 108 |
+
"""
|
| 109 |
+
Bonus for exceptional compression (>20x):
|
| 110 |
+
f(r) = 1.0 + 0.3 * ln(r / 20)
|
| 111 |
|
| 112 |
+
Logarithmic bonus rewards exceptional performance:
|
| 113 |
+
- At 20x: component = 1.0 (continuous at boundary)
|
| 114 |
+
- At 30x: component β 1.12
|
| 115 |
+
- At 40x: component β 1.21
|
| 116 |
+
- At 60x: component β 1.30 (capped)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
+
Natural log ensures smooth transition from linear region.
|
| 119 |
+
"""
|
| 120 |
+
compression_component = 1.0 + 0.3 * math.log(compression_ratio / 20)
|
| 121 |
+
|
| 122 |
+
compression_component = min(1.3, compression_component)
|
| 123 |
|
| 124 |
# In soft zone, both compression AND quality factor matter
|
| 125 |
# If you're below threshold, you need good compression to recover
|
|
|
|
| 156 |
"""
|
| 157 |
quality_component = 0.7 + 0.3 * min(1.0, vmaf_excess / max_vmaf_excess)
|
| 158 |
|
| 159 |
+
# Calculate compression component (compression_rate < 0.80 guaranteed by CASE 0)
|
| 160 |
+
compression_ratio = 1 / compression_rate
|
| 161 |
+
|
| 162 |
+
if compression_ratio <= 20:
|
|
|
|
|
|
|
|
|
|
| 163 |
"""
|
| 164 |
+
Good compression scoring (1.25x to 20x):
|
| 165 |
+
f(r) = ((r - 1.25) / 18.75) ^ 1.2
|
| 166 |
|
| 167 |
+
Starting from 1.25x to give smooth transition from poor zone:
|
| 168 |
+
- At 1.25x: component = 0.025
|
| 169 |
+
- At 2x: component β 0.24
|
| 170 |
+
- At 5x: component β 0.64
|
| 171 |
+
- At 10x: component β 0.88
|
| 172 |
+
- At 15x: component β 0.96
|
| 173 |
+
- At 20x: component = 1.0
|
| 174 |
|
| 175 |
+
The exponent 1.2 provides balanced reward curve.
|
| 176 |
"""
|
| 177 |
+
compression_component = ((compression_ratio - 1.25) / 18.75) ** 1.2 + 0.025
|
|
|
|
|
|
|
|
|
|
| 178 |
else:
|
| 179 |
+
"""
|
| 180 |
+
Exceptional compression bonus (>20x):
|
| 181 |
+
f(r) = 1.0 + 0.3 * ln(r / 20)
|
| 182 |
|
| 183 |
+
Logarithmic bonus up to 1.3 cap:
|
| 184 |
+
- At 20x: component = 1.0 (continuous at boundary)
|
| 185 |
+
- At 30x: component β 1.12
|
| 186 |
+
- At 40x: component β 1.21
|
| 187 |
+
- At 60x: component β 1.30 (capped)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
|
| 189 |
+
Natural log ensures smooth transition from power region.
|
| 190 |
+
"""
|
| 191 |
+
compression_component = 1.0 + 0.3 * math.log(compression_ratio / 20)
|
| 192 |
+
|
| 193 |
+
compression_component = min(1.3, compression_component)
|
| 194 |
+
reason_suffix = "" if compression_ratio < 10 else " (excellent compression)"
|
| 195 |
|
| 196 |
"""
|
| 197 |
Final score is weighted combination:
|