PSNRStatic :计算峰值信噪比。这个工程可以说是JMVC里最最最简单的工程了。今天翻开一看,登时无语:竟然连C++都用不上,两个结构体就可以了。先看可执行文件的调用格式:
PSNRStatic <w> <h> <org> <rec> [<t> [<skip> [<strm> <fps>]]]
w: original width (luma samples)
h: original height (luma samples)
org: original file
rec: reconstructed file
t: number of temporal downsampling stages (default: 0)
skip: number of frames to skip at start (default: 0)
strm: coded stream
fps: frames per second
前13帧的数据。
0 32,7034 37,2575 37,3829
1 32,0109 37,2741 37,2970
2 31,9856 37,2968 37,3429
3 32,0750 37,3475 37,3395
4 31,9481 37,3290 37,4099
5 31,9870 37,2369 37,4276
6 32,1370 37,2644 37,5096
7 31,9204 37,2156 37,5843
8 31,9766 37,2990 37,5438
9 32,0651 37,3211 37,6966
10 31,8719 37,3542 37,7857
11 32,2877 37,4581 37,9061
12 33,0508 37,5689 37,9372
13 32,1267 37,4468 37,8128
total 31,8918 37,2735 37,1472
这是250帧的平均,实现时也只是直接取了个平均而已。
计算的方法是:假设序列a是原始数据,序列b是重建数据。计算ssd=∑(ai-bi)^2,即差的平方和,代码ssd += (double)( diff * diff );,然后
return ( 10.0 * log10( (double)rec.width * (double)rec.height * 65025.0 / ssd ) );
即 a= witdh*height*65025/ssd,再取snr=10log10(a)即可。如果ssd=0,snr=99.99
计算时,是YUV三个分开算的。精确度小数点四位。
参数:
在循环时,会跳过一些帧。
skip_at_start 和skip_between :第一次,跳过开头的skip_at_start个 帧,后来,每次都跳过skip_between个帧。
<skip>:
skip_at_start = atoi ( argv[6] );
for( skip = skip_at_start, index = 0; ...)
开头跳过的帧数,不跳过的话为0.
<t> t: number of temporal downsampling stages (default: 0)
skip_between = ( 1 << temporal_stages ) - 1; temporal_stages就是t。t的值一般是0,1,2,。。0的话就每帧都要,1的话,预测层次中最底层,也就是最后才被预测出来的B帧就被跳过了,依次类推。
以GOP=8为例:
I1 B1 B2 B3 B4 B5 B6 B7 I2
预测的层次:
I1 B4 I2
B2 B6
B1 B3 B5 B7
t=0的话,所有的帧都要。
t=1的话,循环时会跳过一个。得到的是I1 B2 B4 B6 I2,把最底层的B1,B3,B5,B7给去掉了。
t=2时,跳过3个,得到的是I1,B4,I2,
t=3时,则只剩I1, I2,只剩 I 帧了。
如果后面两个参数还有,那么:
if( argc >= 9 )
{
str_file = fopen ( argv[7], "rb" );
fps = atof ( argv[8] );
stream = 1;
}
。。。
if( stream )
{
fseek( str_file, 0, SEEK_END );
bitrate = (double)ftell(str_file) * 8.0 / 1000.0 / ( (double)(sequence_length << temporal_stages) / fps );
fseek( str_file, 0, SEEK_SET );
}
br = (int)floor( acc * bitrate + 0.5 );
最后两个参数,事实上用于计算码率。精确到4位小数,最后同平均信噪比一起输出。码率跟输入的两个yuv文件一点关系也没有,而且需要指定一个已编码的码流文件。
设文件的字节数为n_f,
8 * n_f * fps
bitrate = ------------------------------- , 单位是 k bit/s,表示播放时的平均码流速率。
帧数 * 2^t * 1000
乘的这个8比较诡异,觉得不该乘,这样t只有等于3才正确了。难度8指的是8路视点?好像也不对,
帧数是总的帧数,不受前面跳过的影响。fps是播放的频率,每秒放几帧。