φ(..)メモメモ。FFMpegとNVEncCでお手軽VFRエンコード。同一フレームを間引いてVFR化してみた(設定はサンプルです。御自分の設定を使ってね)

日記 > PC

[VFRの技術検証です。すべての動画にVFR化を進めるものではございませんm(__)m]

今回は編集する人には音ズレで鬼門となるトラウマVFRです!(笑)
本当は圧縮されてほぼ更新が無いフレームになるはずなのですが、GOPの内容(I・P・BフレームとかGOPの長さとかとか)によって60fpsのゲーム画面だと2割くらい無駄があるようです。

■ 2割縮むなら手間かけるよね!

というわけで、どういう風に詰めるのかと試行錯誤していたものの、私の力では2度手間な上に劣化することが判明(^◇^;
べたなパワーエンコード手法をご紹介。

1、FFMpeg で mpdecimate をかけて重複フレームを間引く(削除)
2、NVEncC でエンコードヽ(*^。^*)ノ

わざわざ書くほどでもなかった(;^_^A アセアセ・・・

■ FFMpeg :「mpdecimate」

詳細はマニュアルや解説サイトを参照してください。単純1/2や同じ1/2でもフレームレートに合わせたりプルダウン周り24fps化などいろいろ使い道があるようです。
NVEncCにも間引く機能が追加されているので、アニメだ映画だ24fpsだテレシネプルダウンなんじゃそりゃ!っていう人はいろいろ勉強して一番良い方法を模索してください。

5フレーム以上の連続したフレームが発生しやすいゲーム画面(トイレとか水分補給とか^^;)の無駄なフレーム減らせたらなぁという話です。
Youtubeにあげたりとかそういう目的には合いませんので、その場合はVFR動画もCFR動画に変換したほうが編集時などに音ズレもしにくいのでケースバイケースで。

◆[ffmpeg_mpd.bat]mpdecimateバッチファイル例(i7-6700 + RTX2060-OC環境です)
[ffmpeg.exeにパスは通してあるものとします]

set BEFORE=%~1
set FILENAME=%~n1
set EXTENSION=%~x1
set AFTER=d:\%FILENAME%_mpd%EXTENSION%

ffmpeg -hwaccel cuda -i "%BEFORE%" -vcodec hevc_nvenc -vsync vfr -vf mpdecimate -pix_fmt p010le -preset hq -profile:v main10 -rc constqp -global_quality 2 -codec:a copy "%AFTER%"

※圧縮qpなどは環境などに合わせて好みでどうぞ。

※lossless使いましょうという助言をいただきました(;^_^A アセアセ・・・

ffmpeg -i hoge.mp4 -c:v huffyuv output.avi
ffmpeg -i hoge.mp4 -c:v ffv1 output.avi
ffmpeg -i hoge.mp4 -c:v libx264 -crf 0 output.mp4
ffmpeg -i hoge.mp4 -c:v libx265 -x265-params lossless=1 output.mp4
ffmpeg -i hoge.mp4 -c:v libvpx-vp9 -lossless 1 output.webm

※NVEncCを使わず、一度でエンコードしたらっていう話も。

Added the best hevc_nvenc constqp argument. · nyanshiba/best-ffmpeg-arguments@dcb63ee
Contribute to nyanshiba/best-ffmpeg-arguments development by creating an account on GitHub.
@@ -17,3 +17,22 @@ hevc_nvenc, h264_nvenc, h264_qsv
– FFmpeg version 4.3.1
– FFmpeg version 20200806-2c35797
https://ffmpeg.zeranoe.com/builds/

## hevc_nvenc constqp

“`
ffmpeg version git-2020-08-06-2c35797 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 10.2.1 (GCC) 20200805
configuration: –disable-static –enable-shared –enable-gpl –enable-version3 –enable-sdl2 –enable-fontconfig –enable-gnutls –enable-iconv –enable-libass –enable-libdav1d –enable-libbluray –enable-libfreetype –enable-libmp3lame –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libopenjpeg –enable-libopus –enable-libshine –enable-libsnappy –enable-libsoxr –enable-libsrt –enable-libtheora –enable-libtwolame –enable-libvpx –enable-libwavpack –enable-libwebp –enable-libx264 –enable-libx265 –enable-libxml2 –enable-libzimg –enable-lzma –enable-zlib –enable-gmp –enable-libvidstab –enable-libvmaf –enable-libvorbis –enable-libvo-amrwbenc –enable-libmysofa –enable-libspeex –enable-libxvid –enable-libaom –enable-libgsm –enable-librav1e –disable-w32threads –enable-libmfx –enable-ffnvcodec –enable-cuda-llvm –enable-cuvid –enable-d3d11va –enable-nvenc –enable-nvdec –enable-dxva2 –enable-avisynth –enable-libopenmpt –enable-amf
libavutil 56. 58.100 / 56. 58.100
libavcodec 58. 99.100 / 58. 99.100
libavformat 58. 49.100 / 58. 49.100
libavdevice 58. 11.101 / 58. 11.101
libavfilter 7. 87.100 / 7. 87.100
libswscale 5. 8.100 / 5. 8.100
libswresample 3. 8.100 / 3. 8.100
libpostproc 55. 8.100 / 55. 8.100
“`
“`
ffmpeg -i input.mp4 -c:v hevc_nvenc -preset:v p7 -profile:v main10 -rc:v constqp -rc-lookahead 0 -spatial-aq 0 -temporal-aq 0 -weighted_pred 0 -init_qpI 22 -init_qpP 22 -init_qpB 22 -b_ref_mode 1 -dpb_size 4 -multipass 2 -g 350 -bf 3 -pix_fmt yuv420p10le output.mp4
“`

( ゚o゚)ハッシャープフィルタ使わないなら…あ、先にかけちゃえばいいのか!

※いやいや、FFMpegで掛ければいいじゃん!という話に続く。
「輪郭を保護しながらシャープにしたりぼかしたりする UNSHARP」

輪郭を保護しながらシャープにしたりぼかしたりする unsharp | ニコラボ
似たフィルタに smartblur があり、こちらもぼかしたりシャープにできる。RGB の映像は YUV に変換され、輝度だけ、彩度だけ、また両方にフィルタを掛けられる。

個人的な好みですが、FFMpegのunsharp使うとNVEncCよりファイルサイズがちょっと大きくなる傾向が。設定煮詰めないといけないんですが…

→ファイル数が多いときはPowerShell使いましょ。
◆(call_mpd.ps1)mpdecimateバッチファイルを指定フォルダ(例では ./Source_mp4)内のファイルの数だけ連続で呼び出すPowerShell
[右クリックからPoweShellで実行を選ぶ]

# loop encode.bat
 Write-Host '◆ 指定フォルダのEncodeを開始します';

# 処理対象のフォルダ
 $targetFolder = '.\Source_mp4\';
 $encodeBatFile = '.\ffmpeg_mpd.bat';

function DispNowDateTime{
  $now = Get-Date -format "yyyy/MM/dd HH:mm";
  Write-Host ("`r`n [ " + $now + ' ]');
}

# ----処理開始時間の表示
 DispNowDateTime;

# $targetFolder内のファイル・フォルダのリストを取得する。
 $itemList = Get-ChildItem $targetFolder -File | Sort-Object Name;

#全件数の表示
 $num = ($itemList | Measure-Object).Count
  Write-Host (' ( ' + $num + ' 件) -- 指定フォルダ内のファイル数') ;

#カウント設定
 $enccount = 1;

 foreach($item in $itemList)
 {
    if($item.PSIsContainer)
    {
        # フォルダの場合の処理
        Write-Host ($item.Name + 'はフォルダです。');
    }
    else
    {
        # ファイルの場合の処理
        Write-Host ('( ' + [String]$enccount++ + '/ ' + $num + ') エンコードを開始してProcessの終了を待ちます');
        Write-Host '['$item.Name']';


        $DIRFILE = '"' + $item.FullName + '"';

        #特定のProcessが終了するのを待つ
		$batobj = Start-Process $encodeBatFile ${DIRFILE} -PassThru;
		Wait-Process -Id ($batobj.id);
		Write-Host ("id=$($batobj.id)のProcessが終了しました");

		# ----処理終了時間の表示
		DispNowDateTime;

    }
 }

 Write-Host ' [ Fin ]';

pause

やたらでかいmp4が出来上がると思います(;^_^A アセアセ・・・
mpc-hpなどでコマ送りして重複フレームが間引かれているのが確認できると思います。
後は煮るなり焼くなりフィルタ掛けて仕上げちゃいましょう!(笑)

■ VFRを保持したままNVEncCでエンコードする[–avsync vfr]

「–avsync vfr」はavhwなど使用条件があります。詳しくはオプション解説を読んでね。

AverMediaの外付録画は一度HDMIを通すこともあって、ぼやけるんです…さらにフルレンジがリミテッドレンジになります。
なので少~しシャープ系フィルタをかけてパリッとした感じにフィルタ掛けてみました↓

◆[nvencc_enc.bat]encodeバッチファイル例(i7-6700 + RTX2060-OC環境です)

D:\NVEncC_5.17_x64\NVEncC64.exe -c hevc --profile main10 --output-depth 10 --bref-mode each --ref 16 --avhw --input-analyze 16 --avsync vfr --aq --aq-temporal --aq-strength 0 --vbrhq 0 --vbr-quality 28 --lookahead 32 --gop-len 600 --bframes 4 --vpp-unsharp radius=3,weight=0.5,threshold=10 --audio-copy -i "%~1" -o "d:\(enc)%~n1.mp4" 2>"d:\(enc)%~n1.log"

※いろいろ盛ってみたバッチファイル例。GPU温度とソースによりますがFHDで300fpsくらいは軽く出るかと。温度はOCに影響します。50度以下なら(`・ω・´)bグー
キモは[–achw]と[–avsync vfr]指定だけです。

◆実写テスト:23分40秒(OC追い風参考)

--------------------------------------------------------------------------------
d:\(enc)実写テスト_mpd.mp4
--------------------------------------------------------------------------------
NVEncC (x64) 5.17 (r1669) by rigaya, Oct 15 2020 13:21:44 (VC 1916/Win/avx2)
OS Version     Windows 10 x64 (19042)
CPU            Intel Core i7-6700 @ 3.40GHz [TB: 3.89GHz] (4C/8T)
GPU            #0: GeForce RTX 2060 (1920 cores, 1830 MHz)[PCIe3x16][456.71]
NVENC / CUDA   NVENC API 10.0, CUDA 11.1, schedule mode: auto
Input Buffers  CUDA, 45 frames
Input Info     avcuvid: H.265/HEVC, 1920x1080, 30000/1001 fps
AVSync         vfr
Vpp Filters    cspconv(p010 -> yv12(16bit))
               unsharp: radius 3, weight 0.5, threshold 10.0
               cspconv(yv12(16bit) -> p010)
Output Info    H.265/HEVC main10 @ Level auto
               1920x1080p 1:1 29.970fps (30000/1001fps)
               avwriter: hevc, aac => mp4
Encoder Preset default
Rate Control   VBR
Multipass      2pass-full
Bitrate        0 kbps (Max: 24000 kbps)
Target Quality 28.00
Initial QP     I:20  P:23  B:25
VBV buf size   auto
Lookahead      on, 32 frames, Adaptive I, B Insert
GOP length     600 frames
B frames       4 frames [ref mode: each]
Ref frames     16 frames, MultiRef L0:auto L1:auto
AQ             on
CU max / min   auto / auto
Others         mv:auto repeat-headers 
--中略--
[29.6%] 5114 frames: 313.45 fps, 3826 kb/s, remain 0:00:39, GPU 48%, VE 96%, VD 35%, est out size 262.8MB
[30.3%] 5384 frames: 314.56 fps, 3853 kb/s, remain 0:00:39, GPU 47%, VE 98%, VD 53%, est out size 272.7MB
[30.9%] 5662 frames: 316.00 fps, 3809 kb/s, remain 0:00:40, GPU 48%, VE 97%, VD 47%, est out size 277.7MB
[31.5%] 5921 frames: 316.31 fps, 3850 kb/s, remain 0:00:41, GPU 45%, VE 98%, VD 38%, est out size 288.3MB
[32.0%] 6186 frames: 316.92 fps, 3872 kb/s, remain 0:00:41, GPU 46%, VE 98%, VD 40%, est out size 297.3MB
[32.4%] 6369 frames: 313.44 fps, 3848 kb/s, remain 0:00:42, GPU 27%, VE 55%, VD 24%, est out size 300.6MB
[33.0%] 6637 frames: 314.12 fps, 3886 kb/s, remain 0:00:43, GPU 46%, VE 98%, VD 73%, est out size 310.9MB
[33.6%] 6898 frames: 314.56 fps, 3936 kb/s, remain 0:00:43, GPU 45%, VE 96%, VD 72%, est out size 321.3MB
[34.3%] 7146 frames: 314.32 fps, 4024 kb/s, remain 0:00:44, GPU 46%, VE 98%, VD 87%, est out size 333.5MB
[34.9%] 7396 frames: 314.26 fps, 4103 kb/s, remain 0:00:44, GPU 46%, VE 96%, VD 65%, est out size 346.2MB
[35.4%] 7628 frames: 313.45 fps, 4174 kb/s, remain 0:00:44, GPU 40%, VE 85%, VD 59%, est out size 357.7MB
[36.0%] 7888 frames: 313.79 fps, 4234 kb/s, remain 0:00:45, GPU 46%, VE 94%, VD 66%, est out size 369.0MB
[36.4%] 8059 frames: 310.53 fps, 4258 kb/s, remain 0:00:45, GPU 44%, VE 93%, VD 59%, est out size 375.5MB
[36.8%] 8258 frames: 308.68 fps, 4298 kb/s, remain 0:00:46, GPU 24%, VE 47%, VD 36%, est out size 383.4MB
[37.4%] 8510 frames: 308.86 fps, 4353 kb/s, remain 0:00:46, GPU 45%, VE 94%, VD 76%, est out size 394.5MB
[37.9%] 8748 frames: 308.52 fps, 4411 kb/s, remain 0:00:46, GPU 44%, VE 94%, VD 79%, est out size 404.9MB
[38.5%] 9001 frames: 308.71 fps, 4483 kb/s, remain 0:00:47, GPU 45%, VE 96%, VD 85%, est out size 417.2MB
[39.0%] 9248 frames: 308.68 fps, 4527 kb/s, remain 0:00:47, GPU 43%, VE 91%, VD 68%, est out size 427.1MB
[39.6%] 9500 frames: 308.82 fps, 4582 kb/s, remain 0:00:47, GPU 45%, VE 94%, VD 70%, est out size 437.7MB
[40.2%] 9773 frames: 309.63 fps, 4573 kb/s, remain 0:00:47, GPU 48%, VE 97%, VD 52%, est out size 442.7MB
[40.8%] 10049 frames: 310.47 fps, 4543 kb/s, remain 0:00:47, GPU 48%, VE 98%, VD 45%, est out size 445.1MB
[41.4%] 10329 frames: 311.43 fps, 4518 kb/s, remain 0:00:47, GPU 49%, VE 97%, VD 46%, est out size 448.0MB
[42.0%] 10604 frames: 312.18 fps, 4483 kb/s, remain 0:00:47, GPU 48%, VE 97%, VD 42%, est out size 450.3MB
[42.5%] 10837 frames: 311.24 fps, 4481 kb/s, remain 0:00:47, GPU 44%, VE 90%, VD 59%, est out size 454.3MB
[43.1%] 11093 frames: 311.41 fps, 4467 kb/s, remain 0:00:47, GPU 33%, VE 68%, VD 36%, est out size 457.1MB
--中略--
encode time 0:02:14, CPU: 8.9, GPU: 47.5, VE: 86.2, VD: 42.8, GPUClock: 1984MHz, VEClock: 1834MHz
frame type IDR   321
frame type I     321,  avgQP  23.07,  total size   30.64 MB
frame type P    9331,  avgQP  23.72,  total size  370.85 MB
frame type B   32210,  avgQP  25.55,  total size  328.36 MB
■ 苦労のわりにまとめると2行しかなかった(笑)

そんなもんですよね。
コマンドラインなので当たり前ですが、たたき台のネタ提供としてはそれなりに反響があって…(T.T)
ロスレスじゃない中間ファイルなんてクズのすることだ!ごみファイル推奨するなと!(^◇^;
はい。その通りです。その他罵詈雑言人格否定ありがとうございます。
みんなそう言われてきたんだなぁと。心おられてきたんだなぁと。おかわいそう(´・ω・`)カワイソス

まさかそのまま使うとは(;^_^A アセアセ・・・
自分の目を信じて調整してください。
老眼のじじぃにはほかにかける言葉が見つかりません。

いろいろハマって、もっとボリュームがある印象だったのですが、残念です(^◇^;
日本ではいらない子扱いされてる、音のずれやすい癖のあるVFRにみんな興味があるようで、ネタぶっこんでよかったなぁとヽ(*^。^*)ノ

VFR知らずにエンコードかけると音がずれちゃいますものね…fpsタイミング合わないとフレームスキップするプレイヤーというかコーデックだとカクカクになりますものね…
いらないフレーム表示処理を行わない環境に優しい手法で採用も増えているのに、監視カメラやゲーム業界以外ではなんでVFRにしてんだよって悲しい扱いですよね
正しい知識をみんなが持てば差別も無くなるのに。・゚・(つД゜)・゚・

お前が言うか!(笑)