xref: /aosp_15_r20/external/libaom/tools/ratectrl_log_analyzer/analyze_ratectrl_log.py (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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