diff --git a/Av1an/VMAF/target_vmaf.py b/Av1an/VMAF/target_vmaf.py index 6ce04ee..511fc37 100644 --- a/Av1an/VMAF/target_vmaf.py +++ b/Av1an/VMAF/target_vmaf.py @@ -1,6 +1,7 @@ #!/bin/env python from math import isnan +from math import log as ln import subprocess from subprocess import STDOUT, PIPE @@ -197,6 +198,12 @@ def get_closest(q_list, q, positive=True): return min(q_list, key=lambda x: abs(x - q)) +def transform_vmaf(vmaf): + if vmaf<99.99: + return -ln(1-vmaf/100) + else: + #return -ln(1-99.99/100) + return 9.210340371976184 def weighted_search(num1, vmaf1, num2, vmaf2, target): """ @@ -210,8 +217,8 @@ def weighted_search(num1, vmaf1, num2, vmaf2, target): :return: Q for new probe """ - dif1 = abs(target - vmaf2) - dif2 = abs(target - vmaf1) + dif1 = abs(transform_vmaf(target) - transform_vmaf(vmaf2)) + dif2 = abs(transform_vmaf(target) - transform_vmaf(vmaf1)) tot = dif1 + dif2 @@ -232,6 +239,42 @@ def target_vmaf(chunk: Chunk, args: Args): score = vmaf_probe(chunk, last_q, args) vmaf_cq.append((score, last_q)) + + if args.vmaf_steps < 3: + #Use Euler's method with known relation between cq and vmaf + vmaf_cq_deriv = -0.18 + ## Formula -ln(1-score/100) = vmaf_cq_deriv*last_q + constant + #constant = -ln(1-score/100) - vmaf_cq_deriv*last_q + ## Formula -ln(1-args.vmaf_target/100) = vmaf_cq_deriv*cq + constant + #cq = (-ln(1-args.vmaf_target/100) - constant)/vmaf_cq_deriv + next_q = int(round(last_q + (transform_vmaf(args.vmaf_target)-transform_vmaf(score))/vmaf_cq_deriv)) + + #Clamp + if next_q < args.min_q: + next_q = args.min_q + if args.max_q < next_q: + next_q = args.max_q + + #Single probe cq guess or exit to avoid divide by zero + if args.vmaf_steps == 1 or next_q == last_q: + return next_q + + #Second probe at guessed value + score_2 = vmaf_probe(chunk, next_q, args) + + #Calculate slope + vmaf_cq_deriv = (transform_vmaf(score_2)-transform_vmaf(score))/(next_q-last_q) + + #Same deal different slope + next_q = int(round(next_q+(transform_vmaf(args.vmaf_target)-transform_vmaf(score_2))/vmaf_cq_deriv)) + + #Clamp + if next_q < args.min_q: + next_q = args.min_q + if args.max_q < next_q: + next_q = args.max_q + + return next_q # Initialize search boundary vmaf_lower = score diff --git a/README.md b/README.md index 764dbfc..3feef6b 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,8 @@ With your own parameters: vmaf_4k_v0.6.1.pkl is 3840x2160 (don't forget about vmaf_path) --vmaf_steps Number of probes for interpolation. - Must be bigger than 3. Optimal is 4-6 probes. Default: 4 + 1 and 2 probes have special cases to try to work with few data points. + Optimal is 4-6 probes. Default: 4 --vmaf_rate Setting rate for vmaf probes (Every N frame used in probe, Default: 4)