0%

Codec Test

前几周帮着做了一下x265对比SVT-AV1的测试,以及实验室让测的HM, x265, SVT-HEVC的测试,以下是关于测试方法以及注意点的一些记录。

Quality

  • 测试质量的时候因为对速度没有要求,所以可以写完脚本随便跑。

  • 质量测试与机器无关,找个跑的快的机器跑就行

  • aom cpu-used 0 特别慢

Speed

  • 速度测试在不同机器上跑,尽量控制其他条件一致

  • 关于速度测试的方法:

    • 同一测试命令,跑多路测试,其中同时跑的路数提前测定,取把cpu跑满(使用率>95%)的最小值。
    • 同一命令跑至少三分钟。
    • 测试结果为多路测试的fps求和。
  • 一些备注:

    • 速度测试这么做的理由:
      • 对于VOD场景,一台Server的能力体现在全负荷工作时,可以达到的编码fps。
      • 测试的目的是表现codec在Intel的CPU上的表现(毕竟目的是卖硬件)。
      • 我测过,对于恰好把CPU跑满和跑满以后在加一路,二者的结果差不多,感觉多跑一路不会有很严重的调度问题。
      • 跑三分钟是为了减小调度以及编码器初始化时间等的影响。
  • 速度测试中的一些问题:

    • 编码器对CPU的使用不是恒定的,多线程的波动比较厉害(因为编码的不同阶段对CPU的使用程度不同吧)
    • SVT-AV1在启动初期是单线程的,可能会对速度标定的测试造成影响。
    • 对于编码器比较快的预设模式,原本的测试序列长度不够,不能达到跑三分钟的需求,所以要对序列做concat,对不同的preset编码不同长度的序列(快预设跑短序列是跑太快了,结果不准;但是慢预设跑长序列就会浪费很多时间)
    • x265和svthevc的比较快的选项编码速度特别快,要concat到很长很长。

Implement

  • 序列concat的方法:yuv序列直接用cat
1
2
3
4
#!/bin/bash
for i in {0..9}; do
cat test.yuv >> concated.yuv
done
  • python测试要跑的路数的时候,用psutil库的psutil.cpu_percent(time)来读取cpu使用率

  • 多进程使用subprocess

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def printAndLog(info, log):
print(info)
log.write(info+"\n")

def execute(cmd, log):
printAndLog(cmd, log)
start = time.time()
try:
o = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
shell=True).decode("UTF-8")
except subprocess.CalledProcessError as e:
print("failed to execute command ", e.output)
raise
delta = time.time() - start
printAndLog(o, log)
readable = str(datetime.timedelta(seconds=delta))
printAndLog("use %f secondes(%s)" %(delta, readable), log)
  • 跑完测试之后的分析,主要是提取PSNR、Bitrate和计算BDRATE
    • PSNR有两种方式:
      • 直接从编码器给出的报告提取
      • 用ffmpeg计算
      • 这里的问题在于编码器给的可能不全(其实Average PSNR也可以通过YUV三个通道的自己算)
    • Bitrate也有两种方法:
      • 直接从编码器给出的报告提取
      • 用ffprobe提取,但是码流文件是无法使用ffprobe的,还得先用ffmpeg转成 mp4 才可以提取,很麻烦!
    • 从log中提取PSNR和FPS有两种方法:
      • bash脚本,grep + awk
      • python脚本, re库正则匹配
1
2
3
4
5
6
# calculate PSNR by ffmpeg
ffmpeg -s 1920x1080 -i Ref.yuv -i test.bin -lavfi psnr -f null -
# transcode .bin to .mp4
ffmpeg -i test.bin -c:v copy test.mp4
# ffprobe get bitrate
ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1 test.mp4
1
2
3
4
5
6
7
8
from bjontegaard_metric import *
R1 = np.array([686.76, 309.58, 157.11, 85.95])
PSNR1 = np.array([40.28, 37.18, 34.24, 31.42])
R2 = np.array([893.34, 407.8, 204.93, 112.75])
PSNR2 = np.array([40.39, 37.21, 34.17, 31.24])

print 'BD-PSNR: ', BD_PSNR(R1, PSNR1, R2, PSNR2)
print 'BD-RATE: ', BD_RATE(R1, PSNR1, R2, PSNR2)
  • 同事的脚本写的比较乱,但已经都测完了,我没事也不是很想去清理~

欢迎关注我的其它发布渠道