1#!/usr/bin/python3 2## 3## Copyright (c) 2022, Alliance for Open Media. All rights reserved. 4## 5## This source code is subject to the terms of the BSD 2 Clause License and 6## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 7## was not distributed with this source code in the LICENSE file, you can 8## obtain it at www.aomedia.org/license/software. If the Alliance for Open 9## Media Patent License 1.0 was not distributed with this source code in the 10## PATENTS file, you can obtain it at www.aomedia.org/license/patent. 11## 12""" Analyze the log generated by experimental flag CONFIG_RATECTRL_LOG.""" 13 14import matplotlib.pyplot as plt 15import os 16 17 18def get_file_basename(filename): 19 return filename.split(".")[0] 20 21 22def parse_log(log_file): 23 data_list = [] 24 with open(log_file) as fp: 25 for line in fp: 26 dic = {} 27 word_ls = line.split() 28 i = 0 29 while i < len(word_ls): 30 dic[word_ls[i]] = float(word_ls[i + 1]) 31 i += 2 32 data_list.append(dic) 33 fp.close() 34 return data_list 35 36 37def extract_data(data_list, name): 38 arr = [] 39 for data in data_list: 40 arr.append(data[name]) 41 return arr 42 43 44def visualize_q_indices(exp_summary, exp_list, fig_path=None): 45 for exp in exp_list: 46 data = parse_log(exp["log"]) 47 q_indices = extract_data(data, "q") 48 plt.title(exp_summary) 49 plt.xlabel("frame_coding_idx") 50 plt.ylabel("q_index") 51 plt.plot(q_indices, marker=".", label=exp["label"]) 52 plt.legend() 53 if fig_path: 54 plt.savefig(fig_path) 55 else: 56 plt.show() 57 plt.clf() 58 59 60def get_rc_type_from_exp_type(exp_type): 61 if exp_type == "Q_3P": 62 return "q" 63 return "vbr" 64 65 66def test_video(exe_name, input, exp_type, level, log=None, limit=150): 67 basic_cmd = ("--test-decode=warn --threads=0 --profile=0 --min-q=0 --max-q=63" 68 " --auto-alt-ref=1 --kf-max-dist=160 --kf-min-dist=0 " 69 "--drop-frame=0 --static-thresh=0 --minsection-pct=0 " 70 "--maxsection-pct=2000 --arnr-maxframes=7 --arnr-strength=5 " 71 "--sharpness=0 --undershoot-pct=100 --overshoot-pct=100 " 72 "--frame-parallel=0 --tile-columns=0 --cpu-used=3 " 73 "--lag-in-frames=48 --psnr") 74 rc_type = get_rc_type_from_exp_type(exp_type) 75 rc_cmd = "--end-usage=" + rc_type 76 level_cmd = "" 77 if rc_type == "q": 78 level_cmd += "--cq-level=" + str(level) 79 elif rc_type == "vbr": 80 level_cmd += "--target-bitrate=" + str(level) 81 limit_cmd = "--limit=" + str(limit) 82 passes_cmd = "--passes=3 --second-pass-log=second_pass_log" 83 output_cmd = "-o test.webm" 84 input_cmd = "~/data/" + input 85 log_cmd = "" 86 if log != None: 87 log_cmd = ">" + log 88 cmd_ls = [ 89 exe_name, basic_cmd, rc_cmd, level_cmd, limit_cmd, passes_cmd, output_cmd, 90 input_cmd, log_cmd 91 ] 92 cmd = " ".join(cmd_ls) 93 os.system(cmd) 94 95 96def gen_ratectrl_log(test_case): 97 exe = test_case["exe"] 98 video = test_case["video"] 99 exp_type = test_case["exp_type"] 100 level = test_case["level"] 101 log = test_case["log"] 102 test_video(exe, video, exp_type, level, log=log, limit=150) 103 return log 104 105 106def gen_test_case(exp_type, dataset, videoname, level, log_dir=None): 107 test_case = {} 108 exe = "./aomenc_bl" 109 if exp_type == "BA_3P": 110 exe = "./aomenc_ba" 111 test_case["exe"] = exe 112 113 video = os.path.join(dataset, videoname) 114 test_case["video"] = video 115 test_case["exp_type"] = exp_type 116 test_case["level"] = level 117 118 video_basename = get_file_basename(videoname) 119 log = ".".join([dataset, video_basename, exp_type, str(level)]) 120 if log_dir != None: 121 log = os.path.join(log_dir, log) 122 test_case["log"] = log 123 return test_case 124 125 126def run_ratectrl_exp(exp_config): 127 fp = open(exp_config) 128 log_dir = "./lowres_rc_log" 129 fig_dir = "./lowres_rc_fig" 130 dataset = "lowres" 131 for line in fp: 132 word_ls = line.split() 133 dataset = word_ls[0] 134 videoname = word_ls[1] 135 exp_type_ls = ["VBR_3P", "BA_3P"] 136 level_ls = [int(v) for v in word_ls[2:4]] 137 exp_ls = [] 138 for i in range(len(exp_type_ls)): 139 exp_type = exp_type_ls[i] 140 test_case = gen_test_case(exp_type, dataset, videoname, level_ls[i], 141 log_dir) 142 log = gen_ratectrl_log(test_case) 143 exp = {} 144 exp["log"] = log 145 exp["label"] = exp_type 146 exp_ls.append(exp) 147 video_basename = get_file_basename(videoname) 148 fig_path = os.path.join(fig_dir, video_basename + ".png") 149 visualize_q_indices(video_basename, exp_ls, fig_path) 150 fp.close() 151 152 153if __name__ == "__main__": 154 run_ratectrl_exp("exp_rc_config") 155