| #!/usr/bin/python3 | |
| ## | |
| ## Copyright (c) 2022, Alliance for Open Media. All rights reserved | |
| ## | |
| ## This source code is subject to the terms of the BSD 2 Clause License and | |
| ## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License | |
| ## was not distributed with this source code in the LICENSE file, you can | |
| ## obtain it at www.aomedia.org/license/software. If the Alliance for Open | |
| ## Media Patent License 1.0 was not distributed with this source code in the | |
| ## PATENTS file, you can obtain it at www.aomedia.org/license/patent. | |
| ## | |
| """ Analyze the log generated by experimental flag CONFIG_RATECTRL_LOG.""" | |
| import matplotlib.pyplot as plt | |
| import os | |
| def get_file_basename(filename): | |
| return filename.split(".")[0] | |
| def parse_log(log_file): | |
| data_list = [] | |
| with open(log_file) as fp: | |
| for line in fp: | |
| dic = {} | |
| word_ls = line.split() | |
| i = 0 | |
| while i < len(word_ls): | |
| dic[word_ls[i]] = float(word_ls[i + 1]) | |
| i += 2 | |
| data_list.append(dic) | |
| fp.close() | |
| return data_list | |
| def extract_data(data_list, name): | |
| arr = [] | |
| for data in data_list: | |
| arr.append(data[name]) | |
| return arr | |
| def visualize_q_indices(exp_summary, exp_list, fig_path=None): | |
| for exp in exp_list: | |
| data = parse_log(exp["log"]) | |
| q_indices = extract_data(data, "q") | |
| plt.title(exp_summary) | |
| plt.xlabel("frame_coding_idx") | |
| plt.ylabel("q_index") | |
| plt.plot(q_indices, marker=".", label=exp["label"]) | |
| plt.legend() | |
| if fig_path: | |
| plt.savefig(fig_path) | |
| else: | |
| plt.show() | |
| plt.clf() | |
| def get_rc_type_from_exp_type(exp_type): | |
| if exp_type == "Q_3P": | |
| return "q" | |
| return "vbr" | |
| def test_video(exe_name, input, exp_type, level, log=None, limit=150): | |
| basic_cmd = ("--test-decode=warn --threads=0 --profile=0 --min-q=0 --max-q=63" | |
| " --auto-alt-ref=1 --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 --cpu-used=3 " | |
| "--lag-in-frames=48 --psnr") | |
| rc_type = get_rc_type_from_exp_type(exp_type) | |
| rc_cmd = "--end-usage=" + rc_type | |
| level_cmd = "" | |
| if rc_type == "q": | |
| level_cmd += "--cq-level=" + str(level) | |
| elif rc_type == "vbr": | |
| level_cmd += "--target-bitrate=" + str(level) | |
| limit_cmd = "--limit=" + str(limit) | |
| passes_cmd = "--passes=3 --second-pass-log=second_pass_log" | |
| output_cmd = "-o test.webm" | |
| input_cmd = "~/data/" + input | |
| log_cmd = "" | |
| if log != None: | |
| log_cmd = ">" + log | |
| cmd_ls = [ | |
| exe_name, basic_cmd, rc_cmd, level_cmd, limit_cmd, passes_cmd, output_cmd, | |
| input_cmd, log_cmd | |
| ] | |
| cmd = " ".join(cmd_ls) | |
| os.system(cmd) | |
| def gen_ratectrl_log(test_case): | |
| exe = test_case["exe"] | |
| video = test_case["video"] | |
| exp_type = test_case["exp_type"] | |
| level = test_case["level"] | |
| log = test_case["log"] | |
| test_video(exe, video, exp_type, level, log=log, limit=150) | |
| return log | |
| def gen_test_case(exp_type, dataset, videoname, level, log_dir=None): | |
| test_case = {} | |
| exe = "./aomenc_bl" | |
| if exp_type == "BA_3P": | |
| exe = "./aomenc_ba" | |
| test_case["exe"] = exe | |
| video = os.path.join(dataset, videoname) | |
| test_case["video"] = video | |
| test_case["exp_type"] = exp_type | |
| test_case["level"] = level | |
| video_basename = get_file_basename(videoname) | |
| log = ".".join([dataset, video_basename, exp_type, str(level)]) | |
| if log_dir != None: | |
| log = os.path.join(log_dir, log) | |
| test_case["log"] = log | |
| return test_case | |
| def run_ratectrl_exp(exp_config): | |
| fp = open(exp_config) | |
| log_dir = "./lowres_rc_log" | |
| fig_dir = "./lowres_rc_fig" | |
| dataset = "lowres" | |
| for line in fp: | |
| word_ls = line.split() | |
| dataset = word_ls[0] | |
| videoname = word_ls[1] | |
| exp_type_ls = ["VBR_3P", "BA_3P"] | |
| level_ls = [int(v) for v in word_ls[2:4]] | |
| exp_ls = [] | |
| for i in range(len(exp_type_ls)): | |
| exp_type = exp_type_ls[i] | |
| test_case = gen_test_case(exp_type, dataset, videoname, level_ls[i], | |
| log_dir) | |
| log = gen_ratectrl_log(test_case) | |
| exp = {} | |
| exp["log"] = log | |
| exp["label"] = exp_type | |
| exp_ls.append(exp) | |
| video_basename = get_file_basename(videoname) | |
| fig_path = os.path.join(fig_dir, video_basename + ".png") | |
| visualize_q_indices(video_basename, exp_ls, fig_path) | |
| fp.close() | |
| if __name__ == "__main__": | |
| run_ratectrl_exp("exp_rc_config") |