VMAFで画質比較、パラメータ検討
h264_vaapiでハードウェアエンコードしてたんだが、素材に寄ってはブロックノイズが気になることがあり、もう一度、コーデックも含め、パラメータを検討してみることにした。目視では時間がかかるうえ、客観性も劣る。そこで、VMAFという指標を用いて比較することにした。
VMAFはffmpegのフィルタとして実装されており、エンコ前後の動画を食わせると100点満点で値を返してくる。手元のffmpegをコンパイルし直すのが面倒だったので、ニコニコで配ってるバイナリを引っ張ってきて使用した。
比較するコーデックはh264, h264_vaapi, hevc、それぞれ固定画質モードでエンコードし、ファクタは17から33までひとつおきとした。素材は4種類。洋ドラ、演芸、動物物、アニメ。こんな感じ。
ffmpeg -loglevel 32 -hide_banner -analyzeduration 30M -probesize 30M -i CUT.ts -map 0:0 -map 0:1 -vcodec $CODEC -flags +ildct+ilme -crf $CRF -acodec copy -f mpegts -mpegts_m2ts_mode 1 -vsync 0 $OUTFILE
- vaapiは無いな、と。わざわざエンコードする意味がない。HWエンコはやはり配信用だ。
- hevcとh264、いい勝負なんだが、素材によって得手不得手が有るようだ。
- アニメはh264がいい仕事している。
- 動きの少ない演芸番組、洋ドラ、低ビットレートではhevcが勝る。
- VMAF90点を目標とするなら、hevcでもh264でもqp=27としてエンコードするのがバランスが良いだろう。
- エンコード時間を考えると、h264だな。
- 改めてh264の優秀さに脱帽。
#!/usr/bin/R vmaf <- NULL vmaf <- data.frame ( sample=c("endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "endeavour", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "engei", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "neko", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka", "baka"), codec=c("h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "h264_vaapi", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc", "hevc"), q=c(17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33, 17, 19, 21, 23, 25, 27, 29, 31, 33), size=c(40233408, 28410816, 19067712, 13342848, 10179840, 7934592, 6602880, 5611200, 4888128, 58493376, 42685632, 34079040, 20838912, 17428800, 12104064, 9887808, 8582208, 7333440, 30403584, 19525248, 13114752, 9402624, 7192128, 5808192, 4856448, 4212480, 3741504, 151035264, 114034176, 82104768, 56709504, 39038208, 26509056, 18812928, 13984704, 10893888, 180936576, 129821568, 96960768, 60131904, 45524544, 31225920, 22638912, 18226368, 14008320, 84664320, 57035904, 37372224, 24697152, 16933632, 12134592, 9122304, 7165824, 5833920, 154437312, 122170176, 92806464, 67483776, 48272256, 33981696, 25192320, 19374720, 15513600, 195580608, 144600000, 111267264, 72640704, 56917248, 40729728, 30924096, 25297920, 19798848, 96467904, 71329152, 50634048, 34667328, 23605248, 16603968, 12332160, 9608064, 7767552, 49433856, 38120256, 28001280, 20700864, 15813888, 12406848, 10219392, 8692032, 7590144, 89130048, 71908608, 61507008, 44960064, 39323328, 30558528, 25833216, 23206080, 20117568, 34869312, 26099328, 20038272, 15844416, 12858240, 10714560, 9045696, 7749888, 6715392), vmaf=c(97.414223, 97.033137, 96.482038, 95.757239, 94.927476, 93.827896, 92.298622, 90.533203, 88.224027, 97.030416, 96.358609, 95.820635, 94.789654, 93.996665, 92.554915, 90.360646, 88.345397, 85.164701, 96.219444, 95.691093, 95.029160, 94.137422, 92.967064, 91.447516, 89.471573, 87.011807, 83.784730, 98.938432, 98.642856, 98.124073, 97.340494, 96.344059, 94.954042, 93.197262, 91.164133, 88.550417, 98.414272, 97.745381, 97.169063, 95.961049, 94.971345, 93.369077, 91.096610, 88.941571, 85.402841, 96.982160, 96.112228, 95.127002, 94.008808, 92.675871, 90.938491, 88.704656, 85.810726, 82.135652, 98.956203, 98.674420, 98.200277, 97.477086, 96.427196, 94.767823, 92.285201, 89.003958, 84.911819, 98.546474, 97.897274, 97.294441, 95.725487, 94.356864, 91.833858, 88.033021, 84.286361, 78.460347, 97.610464, 96.862611, 95.852296, 94.467861, 92.648679, 90.275109, 87.202078, 83.337630, 78.449135, 97.403659, 97.187608, 96.859229, 96.446676, 96.002653, 95.345043, 94.579849, 93.621566, 92.440076, 97.229073, 96.942756, 96.600447, 96.138650, 95.621452, 94.792517, 93.501437, 92.044247, 89.634072, 96.659194, 96.318148, 95.893010, 95.349360, 94.573302, 93.521138, 92.015785, 90.099163, 87.699080) ) vmaf <- data.frame (vmaf, bitrate=vmaf$size / 1000 / 60 * 8) png ("vmaf.png", width=960, height=540) xr=c(500, 30000) lt="x" # x <- subset (vmaf, sample=="endeavour"); cc=hsv (0, 1, 1); plot (x[which(x$codec=="h264"),]$bitrate, x[which(x$codec=="h264"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), xlab="Bitrate (kb/s)", ylab="VMAF Score", type="b", col=cc, pch=0) par(new=T) plot (x[which(x$codec=="h264_vaapi"),]$bitrate, x[which(x$codec=="h264_vaapi"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=1) par(new=T) plot (x[which(x$codec=="hevc"),]$bitrate, x[which(x$codec=="hevc"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=2) par(new=T) # x <- subset (vmaf, sample=="engei"); cc=hsv (0.25, 1, 1) plot (x[which(x$codec=="h264"),]$bitrate, x[which(x$codec=="h264"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=0) par(new=T) plot (x[which(x$codec=="h264_vaapi"),]$bitrate, x[which(x$codec=="h264_vaapi"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=1) par(new=T) plot (x[which(x$codec=="hevc"),]$bitrate, x[which(x$codec=="hevc"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=2) par(new=T) # x <- subset (vmaf, sample=="neko"); cc=hsv (0.5, 1, 1) plot (x[which(x$codec=="h264"),]$bitrate, x[which(x$codec=="h264"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=0) par(new=T) plot (x[which(x$codec=="h264_vaapi"),]$bitrate, x[which(x$codec=="h264_vaapi"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=1) par(new=T) plot (x[which(x$codec=="hevc"),]$bitrate, x[which(x$codec=="hevc"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=2) xx <- subset (x, codec=="h264_vaapi") text (xx$bitrate, xx$vmaf, xx$q, pos=4, col=cc, cex=0.75) # text (x[9,]$bitrate, x[9,]$vmaf, x[9,]$codec, pos=4, col=cc) par(new=T) # x <- subset (vmaf, sample=="baka"); cc=hsv (0.75, 1, 1) plot (x[which(x$codec=="h264"),]$bitrate, x[which(x$codec=="h264"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=0) par(new=T) plot (x[which(x$codec=="h264_vaapi"),]$bitrate, x[which(x$codec=="h264_vaapi"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=1) par(new=T) plot (x[which(x$codec=="hevc"),]$bitrate, x[which(x$codec=="hevc"),]$vmaf, log=lt, xlim=xr, ylim=c(70, 100), axes=F, xlab="", ylab="", type="b", col=cc, pch=2) legend (10000, 90, c("h264", "h264_vaapi", "hevc"), pch=0:3) legend (10000, 84, c("endeavour", "engei", "neko", "baka"), col=c(hsv(c(0, 0.25, 0.5, 0.75), 1, 1)), lty=1) title ("VMAF Comparison") dev.off() #