我正在尝试使用 FFmpeg 使用 hevc_nvenc 将多个视频文件从 AVC 转换为 HEVC,并且在最后一刻转换文件后,它给了我这个错误:
[hevc_nvenc @ 00000293155d5880] Failed locking bitstream buffer: not enough buffer (14): .35x
Video encoding failed
[aac @ 0000021d74665040] Qavg: 585.557
[aac @ 0000021d74665040] 2 frames left in the queue on closing
Conversion Failed
并在开始转换之前出现以下警告:
[aac @ 000001387b19d040] Estimating duration from bitrate, this may be inaccurate
我的 FFmpeg 命令:
ffmpeg.exe -hwaccel nvdec -i '.\videoFileInput.mkv' -map 0 -c:v hevc_nvenc -rc:v vbr -tune hq -preset p5 -multipass 1 -bf 4 -b_ref_mode 1 -spatial-aq 1 -aq-strength 8 -cq 32 -c:a aac -b:a 250K -c:s mov_text '.\videoFileOutput.mp4'
我的 GPU:RTX2060 | 图灵架构
对于很多视频文件来说,这个问题不会发生,有时它们有相似的编解码器和属性,只是其中一个不起作用
其中一个文件的 MediaInfo 信息
Complete name : drive/videofile.mkv
Format : Matroska
Format version : Version 4
File size : 1.14 GiB
Duration : 26 min 32 s
Overall bit rate mode : Variable
Overall bit rate : 6 142 kb/s
Encoded date : UTC 2018-07-18 05:01:14 / UTC 2018-05-27 01:24:09
Writing application : mkvmerge v21.0.0 ('Tardigrades Will Inherit The Earth') 64-bit
Writing library : libebml v1.3.5 + libmatroska v1.4.8 / Lavf58.0.0
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L4
Format settings : CABAC / 3 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 3 frames
Codec ID : V_MPEG4/ISO/AVC
Duration : 26 min 32 s
Bit rate mode : Variable
Bit rate : 5 620 kb/s
Maximum bit rate : 8 430 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.113
Stream size : 1 021 MiB (88%)
Writing library : x264 core 118
Encoding settings : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=umh / subme=10 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=24 / chroma_me=1 / trellis=2 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=6 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=2 / b_pyramid=0 / b_adapt=2 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=48 / keyint_min=25 / scenecut=0 / intra_refresh=0 / rc_lookahead=0 / rc=2pass / mbtree=1 / bitrate=5620 / ratetol=1.0 / qcomp=0.50 / qpmin=6 / qpmax=51 / qpstep=4 / cplxblur=20.0 / qblur=0.5 / vbv_maxrate=8430 / vbv_bufsize=11240 / nal_hrd=vbr / ip_ratio=1.40 / aq=1:1.00
Default : Yes
Forced : No
Audio
ID : 2
Format : E-AC-3
Format/Info : Enhanced AC-3
Commercial name : Dolby Digital Plus
Codec ID : A_EAC3
Duration : 26 min 32 s
Bit rate mode : Constant
Bit rate : 640 kb/s
Channel(s) : 6 channels
Channel layout : L R C LFE Ls Rs
Sampling rate : 48.0 kHz
Frame rate : 31.250 FPS (1536 SPF)
Compression mode : Lossy
Stream size : 121 MiB (10%)
Language : English
Service kind : Complete Main
Default : Yes
Forced : No
Encoded date : UTC 2018-05-27 01:24:09
ffprobe 信息
Input #0, matroska,webm, from '.\videoFile.mkv':
Metadata:
CREATION_TIME : 2018-05-27 01:24:09
COMPATIBLE_BRANDS: isomiso2dashiso6
MAJOR_BRAND : mp42
MINOR_VERSION : 0
ENCODER : Lavf58.0.0
Duration: 00:26:32.10, start: 0.000000, bitrate: 6141 kb/s
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn (default)
Stream #0:1(eng): Audio: eac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
Metadata:
CREATION_TIME : 2018-05-27 01:24:09
HANDLER_NAME : Audio Media Handler
我到处搜索,找不到解决这个问题的方法
以下是我尝试过的方法
我怀疑问题可能出在视频长度上,于是我尝试用命令剪辑视频,
-ss
结果成功了。对于 26:32 分钟的视频,我可以剪辑到 26:00 分钟,这完全没问题,但原始文件长度无法转换我也尝试了 mkvextract 并提取了 mkv 容器并将它们输入到 ffmpeg 中,但它也不起作用
我的合并 WebM 和 aac 文件的命令
ffmpeg.exe -hwaccel nvdec -i '.\video.webm' -i .\audio.aac -map 0 -map 1 -c:v hevc_nvenc -rc:v vbr -tune hq -preset p5 -multipass 1 -bf 4 -b_ref_mode 1 -spatial-aq 1 -aq-strength 8 -cq 38 -c:a aac -b:a 250K '.\mkv_extract_Merge.mp4'
然后我想可能是因为我的文件扩展名,并尝试将 mp4 更改为 mkv,但它再次不起作用
我尝试了不同的 AVOptions,甚至默认的 AVOptions,但它仍然不起作用
ffmpeg.exe -i ".\video.mkv" -c:v hevc_nvenc -c:a copy ".\outpuFile.mp4"
我尝试了这个
-bufsize:v <int>
选项,并且每次都把它调得越来越高,但没有用- 我不知道缓冲区大小是什么以及它是如何工作的,我尝试了一下,只是想看看它是否是我所面临的问题的根源
它唯一起作用的时候是使用 h264_nvenc 的时候,而且它成功了(我用很少的 AVOptions 尝试过)
我怀疑视频和音频的 fps 不匹配,所以我检查了转换后的视频,发现音频的 fps 有差异,在第一个视频中,如您在上面的日志中看到的那样,它是 31 fps,在其他视频中它是 46,我尝试将音频文件转换为 23.976(视频的 fps),转换
-filter:v fps=23.976
后它变成了 46 fps,然后我尝试使用 ffmpeg 合并它们,但它再次不起作用现在我怀疑音频或视频的时长有问题,因为 ffmpeg 提取它们之后的估计时间是 02:10:32,而视频只有 00:26:32 分钟(这个估计是我尝试合并提取的音频和视频的时间,但是当我尝试转换 mkv 容器时,它估计音频是 00:26:32.10,这与 MediaInfo 的持续时间值相似)
这是转换过程中 FFmpeg 的日志
Input #0, h264, from '.\video.webm':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 24 fps, 23.98 tbr, 1200k tbn
[eac3 @ 000001c3e501d040] Estimating duration from bitrate, this may be inaccurate
Input #1, eac3, from '.\audio.aac':
Duration: 00:26:32.10, start: 0.000000, bitrate: 640 kb/s
Stream #1:0: Audio: eac3, 48000 Hz, 5.1(side), fltp, 640 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> hevc (hevc_nvenc))
Stream #1:0 -> #0:1 (eac3 (native) -> aac (native))
Press [q] to stop, [?] for help
[aac @ 000001c3e4d65040] Using a PCE to encode channel layout "5.1(side)"
Output #0, matroska, to '.\mkv_extract_Merge.mkv':
Metadata:
encoder : Lavf59.2.102
Stream #0:0: Video: hevc (Main), nv12(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 1k tbn
Metadata:
encoder : Lavc59.1.101 hevc_nvenc
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 4000000 vbv_delay: N/A
Stream #0:1: Audio: aac (LC) ([255][0][0][0] / 0x00FF), 48000 Hz, 5.1(side), fltp, 250 kb/s
Metadata:
encoder : Lavc59.1.101 aac
[hevc_nvenc @ 000001c3e4d644c0] Failed locking bitstream buffer: not enough buffer (14): .26x
Video encoding failed
[aac @ 000001c3e4d65040] Qavg: 585.557
[aac @ 000001c3e4d65040] 2 frames left in the queue on closing
Conversion failed!
h264_nvenc 日志:
Input #0, matroska,webm, from '.\videoFile.mkv':
Metadata:
CREATION_TIME : 2018-05-27 01:24:09
COMPATIBLE_BRANDS: isomiso2dashiso6
MAJOR_BRAND : mp42
MINOR_VERSION : 0
ENCODER : Lavf58.0.0
Duration: 00:26:32.10, start: 0.000000, bitrate: 6141 kb/s
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn (default)
Stream #0:1(eng): Audio: eac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
Metadata:
CREATION_TIME : 2018-05-27 01:24:09
HANDLER_NAME : Audio Media Handler
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (h264_nvenc))
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[mp4 @ 00000284a0af0cc0] track 1: codec frame size is not set
Output #0, mp4, to '.\videofile.mp4':
Metadata:
MINOR_VERSION : 0
COMPATIBLE_BRANDS: isomiso2dashiso6
MAJOR_BRAND : mp42
encoder : Lavf59.2.102
Stream #0:0: Video: h264 (Main) (avc1 / 0x31637661), nv12(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2000 kb/s, 23.98 fps, 24k tbn (default)
Metadata:
encoder : Lavc59.1.101 h264_nvenc
Side data:
cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 4000000 vbv_delay: N/A
Stream #0:1(eng): Audio: eac3 (ec-3 / 0x332D6365), 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
Metadata:
CREATION_TIME : 2018-05-27 01:24:09
HANDLER_NAME : Audio Media Handler
frame=38170 fps=359 q=20.0 Lsize= 506687kB time=00:26:32.06 bitrate=2607.2kbits/s speed= 15x
video:381434kB audio:124382kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.171940%
编辑 21年6月16日
我发现了另一条线索:
我对几个具有相同设置的文件运行了脚本,其中几个文件在上述信息中失败了,当我检查它们时,它们有一个“编码设置”部分,其中包含以下文本:
wpp / ctu=16 / tu-intra-depth=1 / tu-inter-depth=1 / me=0 / subme=0 / merange=25 / no-rect / no-amp / max-merge=2 / temporal-mvp / early-skip / no-fast-cbf / rdpenalty=0 / no-tskip / no-tskip-fast / strong-intra-smoothing / no-lossless / no-cu-lossless / no-constrained-intra / fast-intra / no-open-gop / interlace=0 / keyint=30 / min-keyint=1 / scenecut=0 / rc-lookahead=1 / bframes=0 / bframe-bias=0 / b-adapt=0 / ref=1 / no-weightp / no-weightb / aq-mode=0 / aq-strength=0.00 / cbqpoffs=0 / crqpoffs=0 / rd=2 / psy-rd=0.00 / psy-rdoq=0.00 / no-signhide / no-lft / no-sao / no-sao-non-deblock / no-b-pyramid / no-cutree / rc=abr / bitrate=2000 / qcomp=0.60 / qpmin=0 / qpmax=51 / qpstep=4 / ipratio=1.40
cabac=1 / ref=4 / deblock=1:0:0 / analyse=0x3:0x111 / me=umh / subme=10 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=120 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / stitchable=1 / constrained_intra=0 / bframes=16 / b_pyramid=2 / b_adapt=2 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=240 / keyint_min=121 / scenecut=0 / intra_refresh=0 / rc_lookahead=240 / rc=crf / mbtree=1 / crf=16.0 / qcomp=0.50 / qpmin=6 / qpmax=51 / qpstep=4 / vbv_maxrate=20000 / vbv_bufsize=25000 / crf_max=0.0 / nal_hrd=vbr / filler=0 / ip_ratio=1.40 / aq=1:0.80
我不知道哪一个设置可能是导致此错误的原因,但它可能是其中之一。
编辑21年6月24日
这里有一些样本编码有问题的文件。
我尝试修剪有问题的视频(我只修剪了几帧),它删除了Encoding Settings
MediaInfo 中的部分,现在我可以毫无问题地转换它们,似乎这Encoding Settings
就是问题所在。任何关于这个选项是什么以及如何删除它的信息都将不胜感激。
答案1
假设 GPU 驱动程序和 FFmpeg 版本保持不变,解决您的问题的方法是:
-threads 1
1.使用 NVDEC 解码时,将线程数降低至 1(通过),并将-extra_hw_frames
值提升至3
,使用如下代码片段:
ffmpeg.exe -threads 1 -hwaccel nvdec -extra_hw_frames 3 -i '.\videoFileInput.mkv' -map 0 -c:v hevc_nvenc -b:v 0 -rc:v vbr -tune hq -preset p5 -multipass 1 -bf 4 -b_ref_mode 1 -spatial-aq 1 -aq-strength 8 -cq 32 -c:a aac -b:a 250K -c:s mov_text '.\videoFileOutput.mp4'
NVDEC 在多线程下相当脆弱,如果每个上下文的线程和表面数量达到或超过 32,它会发出警告,如下所示这里. 同样适用于硬件表面框架,可以容易耗尽处理具有多个 B 帧和隔行扫描的内容时。
2.更好的是,完全禁用 NVDEC:
ffmpeg.exe -i '.\videoFileInput.mkv' -map 0 -c:v hevc_nvenc -b:v 0 -rc:v vbr -tune hq -preset p5 -multipass 1 -bf 4 -b_ref_mode 1 -spatial-aq 1 -aq-strength 8 -cq 32 -c:a aac -b:a 250K -c:s mov_text '.\videoFileOutput.mp4'
您的编码应该可以继续进行,不会出现其他问题。我添加了一个额外的参数-b:v 0
,该参数会取消设置 NVENC 内部设置的默认比特率,因为使用的是速率控制方法 ( -rc:v vbr
)。
测试并报告。
答案2
您可能需要尝试不同的 ffmpeg 版本。我一直随机遇到这个问题,直到我决定使用某个日期为 2020-03-28 的官方版本(碰巧手头有),而不是我自己的版本,该版本使用 libfdk_aac,时间要晚得多(2021-06-14)。
我也检查过了https://www.gyan.dev/ffmpeg/builds/并且 git-full (2021-08-10)遇到错误,但 release-full (4.4)没有遇到错误。