diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/aom/tools/gop_bitrate | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/aom/tools/gop_bitrate')
3 files changed, 216 insertions, 0 deletions
diff --git a/third_party/aom/tools/gop_bitrate/analyze_data.py b/third_party/aom/tools/gop_bitrate/analyze_data.py new file mode 100644 index 0000000000..4e006b9220 --- /dev/null +++ b/third_party/aom/tools/gop_bitrate/analyze_data.py @@ -0,0 +1,18 @@ +with open('experiment.txt', 'r') as file: + lines = file.readlines() + curr_filename = '' + keyframe = 0 + actual_value = 0 + estimate_value = 0 + print('filename, estimated value (b), actual value (b)') + for line in lines: + if line.startswith('input:'): + curr_filename = line[13:].strip() + if line.startswith('estimated'): + estimate_value = float(line[19:].strip()) + if line.startswith('frame:'): + actual_value += float(line[line.find('size')+6:line.find('total')-2]) + if line.startswith('****'): + print(f'{curr_filename}, {estimate_value}, {actual_value}') + estimate_value = 0 + actual_value = 0 diff --git a/third_party/aom/tools/gop_bitrate/encode_all_script.sh b/third_party/aom/tools/gop_bitrate/encode_all_script.sh new file mode 100755 index 0000000000..0689b33138 --- /dev/null +++ b/third_party/aom/tools/gop_bitrate/encode_all_script.sh @@ -0,0 +1,13 @@ +#!/bin/bash +#INPUT=media/cheer_sif.y4m +OUTPUT=test.webm +LIMIT=17 +CPU_USED=3 +CQ_LEVEL=36 + +for input in media/* +do + echo "****" >> experiment.txt + echo "input: $input" >> experiment.txt + ./aomenc --limit=$LIMIT --codec=av1 --cpu-used=$CPU_USED --end-usage=q --cq-level=$CQ_LEVEL --psnr --threads=0 --profile=0 --lag-in-frames=35 --min-q=0 --max-q=63 --auto-alt-ref=1 --passes=2 --kf-max-dist=160 --kf-min-dist=0 --drop-frame=0 --static-thresh=0 --minsection-pct=0 --maxsection-pct=2000 --arnr-maxframes=7 --arnr-strength=5 --sharpness=0 --undershoot-pct=100 --overshoot-pct=100 --frame-parallel=0 --tile-columns=0 -o $OUTPUT $input >> experiment.txt +done diff --git a/third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py b/third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py new file mode 100644 index 0000000000..2a5da6a794 --- /dev/null +++ b/third_party/aom/tools/gop_bitrate/python/bitrate_accuracy.py @@ -0,0 +1,185 @@ +import numpy as np + +# Model A only. +# Uses least squares regression to find the solution +# when there is one unknown variable. +def lstsq_solution(A, B): + A_inv = np.linalg.pinv(A) + x = np.matmul(A_inv, B) + return x[0][0] + +# Model B only. +# Uses the pseudoinverse matrix to find the solution +# when there are two unknown variables. +def pinv_solution(A, mv, B): + new_A = np.concatenate((A, mv), axis=1) + new_A_inv = np.linalg.pinv(new_A) + new_x = np.matmul(new_A_inv, B) + print("pinv solution:", new_x[0][0], new_x[1][0]) + return (new_x[0][0], new_x[1][0]) + +# Model A only. +# Finds the coefficient to multiply A by to minimize +# the percentage error between A and B. +def minimize_percentage_error_model_a(A, B): + R = np.divide(A, B) + num = 0 + den = 0 + best_x = 0 + best_error = 100 + for r_i in R: + num += r_i + den += r_i**2 + if den == 0: + return 0 + return (num/den)[0] + +# Model B only. +# Finds the coefficients to multiply to the frame bitrate +# and the motion vector bitrate to minimize the percent error. +def minimize_percentage_error_model_b(r_e, r_m, r_f): + r_ef = np.divide(r_e, r_f) + r_mf = np.divide(r_m, r_f) + sum_ef = np.sum(r_ef) + sum_ef_sq = np.sum(np.square(r_ef)) + sum_mf = np.sum(r_mf) + sum_mf_sq = np.sum(np.square(r_mf)) + sum_ef_mf = np.sum(np.multiply(r_ef, r_mf)) + # Divides x by y. If y is zero, returns 0. + divide = lambda x, y : 0 if y == 0 else x / y + # Set up and solve the matrix equation + A = np.array([[1, divide(sum_ef_mf, sum_ef_sq)],[divide(sum_ef_mf, sum_mf_sq), 1]]) + B = np.array([divide(sum_ef, sum_ef_sq), divide(sum_mf, sum_mf_sq)]) + A_inv = np.linalg.pinv(A) + x = np.matmul(A_inv, B) + return x + +# Model A only. +# Calculates the least squares error between A and B +# using coefficients in X. +def average_lstsq_error(A, B, x): + error = 0 + n = 0 + for i, a in enumerate(A): + a = a[0] + b = B[i][0] + if b == 0: + continue + n += 1 + error += (b - x*a)**2 + if n == 0: + return None + error /= n + return error + +# Model A only. +# Calculates the average percentage error between A and B. +def average_percent_error_model_a(A, B, x): + error = 0 + n = 0 + for i, a in enumerate(A): + a = a[0] + b = B[i][0] + if b == 0: + continue + n += 1 + error_i = (abs(x*a-b)/b)*100 + error += error_i + error /= n + return error + +# Model B only. +# Calculates the average percentage error between A and B. +def average_percent_error_model_b(A, M, B, x): + error = 0 + for i, a in enumerate(A): + a = a[0] + mv = M[i] + b = B[i][0] + if b == 0: + continue + estimate = x[0]*a + estimate += x[1]*mv + error += abs(estimate - b) / b + error *= 100 + error /= A.shape[0] + return error + +def average_squared_error_model_a(A, B, x): + error = 0 + n = 0 + for i, a in enumerate(A): + a = a[0] + b = B[i][0] + if b == 0: + continue + n += 1 + error_i = (1 - x*(a/b))**2 + error += error_i + error /= n + error = error**0.5 + return error * 100 + +def average_squared_error_model_b(A, M, B, x): + error = 0 + n = 0 + for i, a in enumerate(A): + a = a[0] + b = B[i][0] + mv = M[i] + if b == 0: + continue + n += 1 + error_i = 1 - ((x[0]*a + x[1]*mv)/b) + error_i = error_i**2 + error += error_i + error /= n + error = error**0.5 + return error * 100 + +# Traverses the data and prints out one value for +# each update type. +def print_solutions(file_path): + data = np.genfromtxt(file_path, delimiter="\t") + prev_update = 0 + split_list_indices = list() + for i, val in enumerate(data): + if prev_update != val[3]: + split_list_indices.append(i) + prev_update = val[3] + split = np.split(data, split_list_indices) + for array in split: + A, mv, B, update = np.hsplit(array, 4) + z = np.where(B == 0)[0] + r_e = np.delete(A, z, axis=0) + r_m = np.delete(mv, z, axis=0) + r_f = np.delete(B, z, axis=0) + A = r_e + mv = r_m + B = r_f + all_zeros = not A.any() + if all_zeros: + continue + print("update type:", update[0][0]) + x_ls = lstsq_solution(A, B) + x_a = minimize_percentage_error_model_a(A, B) + x_b = minimize_percentage_error_model_b(A, mv, B) + percent_error_a = average_percent_error_model_a(A, B, x_a) + percent_error_b = average_percent_error_model_b(A, mv, B, x_b)[0] + baseline_percent_error_a = average_percent_error_model_a(A, B, 1) + baseline_percent_error_b = average_percent_error_model_b(A, mv, B, [1, 1])[0] + + squared_error_a = average_squared_error_model_a(A, B, x_a) + squared_error_b = average_squared_error_model_b(A, mv, B, x_b)[0] + baseline_squared_error_a = average_squared_error_model_a(A, B, 1) + baseline_squared_error_b = average_squared_error_model_b(A, mv, B, [1, 1])[0] + + print("model,\tframe_coeff,\tmv_coeff,\terror,\tbaseline_error") + print("Model A %_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(percent_error_a) + ",\t" + str(baseline_percent_error_a)) + print("Model A sq_error,\t" + str(x_a) + ",\t" + str(0) + ",\t" + str(squared_error_a) + ",\t" + str(baseline_squared_error_a)) + print("Model B %_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(percent_error_b) + ",\t" + str(baseline_percent_error_b)) + print("Model B sq_error,\t" + str(x_b[0]) + ",\t" + str(x_b[1]) + ",\t" + str(squared_error_b) + ",\t" + str(baseline_squared_error_b)) + print() + +if __name__ == "__main__": + print_solutions("data2/all_lowres_target_lt600_data.txt") |