xref: /aosp_15_r20/external/libaom/tools/frame_size_variation_analyzer.py (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1# RTC frame size variation analyzer
2# Usage:
3# 1. Config with "-DCONFIG_OUTPUT_FRAME_SIZE=1".
4# 2. Build aomenc. Encode a file, and generate output file: frame_sizes.csv
5# 3. Run: python ./frame_size.py frame_sizes.csv target-bitrate fps
6#    Where target-bitrate: Bitrate (kbps), and fps is frame per second.
7#    Example: python ../aom/tools/frame_size_variation_analyzer.py frame_sizes.csv
8#    1000 30
9
10import numpy as np
11import csv
12import sys
13import matplotlib.pyplot as plt
14
15# return the moving average
16def moving_average(x, w):
17  return np.convolve(x, np.ones(w), 'valid') / w
18
19def frame_size_analysis(filename, target_br, fps):
20  tbr = target_br * 1000 / fps
21
22  with open(filename, 'r') as infile:
23    raw_data = list(csv.reader(infile, delimiter=','))
24
25  data = np.array(raw_data).astype(float)
26  fsize = data[:, 0].astype(float)  # frame size
27  qindex = data[:, 1].astype(float)  # qindex
28
29  # Frame bit rate mismatch
30  mismatch = np.absolute(fsize - np.full(fsize.size, tbr))
31
32  # Count how many frames are more than 2.5x of frame target bit rate.
33  tbr_thr = tbr * 2.5
34  cnt = 0
35  idx = np.arange(fsize.size)
36  for i in idx:
37    if fsize[i] > tbr_thr:
38      cnt = cnt + 1
39
40  # Use the 15-frame moving window
41  win = 15
42  avg_fsize = moving_average(fsize, win)
43  win_mismatch = np.absolute(avg_fsize - np.full(avg_fsize.size, tbr))
44
45  print('[Target frame rate (bit)]:', "%.2f"%tbr)
46  print('[Average frame rate (bit)]:', "%.2f"%np.average(fsize))
47  print('[Frame rate standard deviation]:', "%.2f"%np.std(fsize))
48  print('[Max/min frame rate (bit)]:', "%.2f"%np.max(fsize), '/', "%.2f"%np.min(fsize))
49  print('[Average frame rate mismatch (bit)]:', "%.2f"%np.average(mismatch))
50  print('[Number of frames (frame rate > 2.5x of target frame rate)]:', cnt)
51  print(' Moving window size:', win)
52  print('[Moving average frame rate mismatch (bit)]:', "%.2f"%np.average(win_mismatch))
53  print('------------------------------')
54
55  figure, axis = plt.subplots(2)
56  x = np.arange(fsize.size)
57  axis[0].plot(x, fsize, color='blue')
58  axis[0].set_title("frame sizes")
59  axis[1].plot(x, qindex, color='blue')
60  axis[1].set_title("frame qindex")
61  plt.tight_layout()
62
63  # Save the plot
64  plotname = filename + '.png'
65  plt.savefig(plotname)
66  plt.show()
67
68if __name__ == '__main__':
69  if (len(sys.argv) < 4):
70    print(sys.argv[0], 'input_file, target_bitrate, fps')
71    sys.exit()
72  target_br = int(sys.argv[2])
73  fps = int(sys.argv[3])
74  frame_size_analysis(sys.argv[1], target_br, fps)
75