ffmpeg 视频在 'Invalid buffer size, packet size < expected frame_size' 错误后垂直滑动(vsync 屏幕撕裂故障)?
ffmpeg video slides vertically after 'Invalid buffer size, packet size < expected frame_size' error (vsync screen tearing glitch)?
我有一个视频,我想使用 opencv 和 ffmpeg 进行剪切和裁剪。
我希望输出为 H265,因此我正在使用 ffmpeg 子进程(将帧字节写入标准输入),如 所述。这是导致错误的代码的最低版本:
import os, shlex, subprocess, cv2, imutils
VIDEO_DIR = '../SoExample' # should contain a file 'in.mpg'
TIMESPAN = (3827, 3927) # cut to this timespan (frame numbers)
CROP = dict(min_x=560, max_x=731, min_y=232, max_y=418) # crop to this area
# calculate output video size
size = (CROP['max_x']-CROP['min_x'], CROP['max_y']-CROP['min_y']) # (w,h)
# ffmpeg throws an error when having odd dimensions that are not dividable by 2,
# so i just add a pixel to the size and stretch the original image by 1 pixel later.
size_rounded = (size[0]+1 if size[0] % 2 != 0 else size[0],
size[1]+1 if size[1] % 2 != 0 else size[1])
# read input video
vid_path_in = os.path.join(VIDEO_DIR, 'in.mpg')
cap = cv2.VideoCapture(vid_path_in)
fps = int(cap.get(cv2.CAP_PROP_FPS))
# generate and run ffmpeg command
ffmpeg_cmd = (f'/usr/bin/ffmpeg -y -s {size_rounded[0]}x{size_rounded[1]} -pixel_format'
+ f' bgr24 -f rawvideo -r {fps} -re -i pipe: -vcodec libx265 -pix_fmt yuv420p'
+ f' -crf 24 -x265-params "ctu=64" "{os.path.join(VIDEO_DIR, "out.mp4")}"')
print("using cmd", ffmpeg_cmd)
process = subprocess.Popen(shlex.split(ffmpeg_cmd), stdin=subprocess.PIPE)
# seek to the beginning of the cutting timespan and loop through frames of input video
cap.set(cv2.CAP_PROP_POS_FRAMES, TIMESPAN[0])
frame_returned = True
while cap.isOpened() and frame_returned:
frame_returned, frame = cap.read()
frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - 1
# check if timespan end is not reached yet
if frame_number < TIMESPAN[1]:
# crop to relevant image area
frame_cropped = frame[CROP['min_y']:CROP['max_y'],
CROP['min_x']:CROP['max_x']]
# resize to even frame size if needed:
if size != size_rounded:
frame_cropped = imutils.resize(frame_cropped, width=size_rounded[0],
height=size_rounded[1])
# Show processed image using opencv: I see no errors here.
cv2.imshow('Frame', frame_cropped)
# Write cropped video frame to input stream of ffmpeg sub-process.
process.stdin.write(frame_cropped.tobytes())
else:
break
# Press Q on keyboard to exit earlier
if cv2.waitKey(25) & 0xFF == ord('q'):
break
process.stdin.close() # Close and flush stdin
process.wait() # Wait for sub-process to finish
process.terminate() # Terminate the sub-process
print("Done!")
不幸的是,我的输出是这样的:
输出不应包含此垂直滑动故障。有谁知道如何修复它?
上述脚本的控制台输出显示:
using cmd /usr/bin/ffmpeg -y -s 172x186 -pixel_format bgr24 -f rawvideo -r 23 -i pipe: -vcodec libx265 -pix_fmt yuv420p -crf 24 -x265-params "ctu=64" "../SoExample/out.mp4"
ffmpeg version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
WARNING: library configuration mismatch
avcodec configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, rawvideo, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: 17659 kb/s
Stream #0:0: Video: rawvideo (BGR[24] / 0x18524742), bgr24, 172x186, 17659 kb/s, 23 tbr, 23 tbn, 23 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (libx265))
x265 [info]: HEVC encoder version 2.6
x265 [info]: build info [Linux][GCC 7.2.0][64 bit] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
x265 [info]: Main profile, Level-2 (Main tier)
x265 [info]: Thread pool created using 4 threads
x265 [info]: Slices : 1
x265 [info]: frame threads / pool features : 2 / wpp(3 rows)
x265 [warning]: Source height < 720p; disabling lookahead-slices
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 2
x265 [info]: Keyframe min / max / scenecut / bias: 23 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0
x265 [info]: References / ref-limit cu / depth : 3 / on / on
x265 [info]: AQ: mode / str / qg-size / cu-tree : 1 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : CRF-24.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 rskip signhide tmvp strong-intra-smoothing
x265 [info]: tools: deblock sao
Output #0, mp4, to '../SoExample/out.mp4':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: hevc (libx265) (hev1 / 0x31766568), yuv420p, 172x186, q=2-31, 23 fps, 11776 tbn, 23 tbc
Metadata:
encoder : Lavc57.107.100 libx265
[rawvideo @ 0x564ebd221aa0] Invalid buffer size, packet size 51600 < expected frame_size 95976
Error while decoding stream #0:0: Invalid argument
frame= 100 fps= 30 q=-0.0 Lsize= 36kB time=00:00:04.21 bitrate= 69.1kbits/s speed=1.25x
video:32kB audio:0kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 12.141185%
x265 [info]: frame I: 1, Avg QP:22.44 kb/s: 179.77
x265 [info]: frame P: 29, Avg QP:24.20 kb/s: 130.12
x265 [info]: frame B: 70, Avg QP:29.99 kb/s: 27.82
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
x265 [info]: consecutive B-frames: 20.0% 3.3% 16.7% 43.3% 16.7%
encoded 100 frames in 3.35s (29.83 fps), 59.01 kb/s, Avg QP:28.23
Done!
如您所见,出现错误:Invalid buffer size, packet size 51600 < expected frame_size 95976 Error while decoding stream #0:0: Invalid argument
,您认为这可能是所显示问题的原因吗?我不确定,因为最后它告诉我所有 100 帧都会被编码。
如果您想在完全相同的视频上重现此内容,您可以在 UCF Aerial Action Dataset 中找到 actions1.mpg
。
非常感谢任何帮助,因为我真的被这个错误困住了。
修复错误比预期的要容易。
imutils.resize()
仅尝试评估宽度或高度参数,而不是两者,并尝试保留图像的原始纵横比,而 cv2.resize()
为您提供自由选择(w/o 任何约束) [Source Code, Explanation]
就我而言,这会导致意外的调整大小行为。我告诉 imutils
将我的 (171, 186)
图像调整为 (172, 186)
,但它所做的是调整为 (172, 187)
,因为它决定宁愿保持纵横比而不是想要的高度,所以它丢弃了我提交的高度。
简单的解决方法是替换
imutils.resize(frame_cropped, width=size_rounded[0], height=size_rounded[1])
来自
cv2.resize(frame_cropped, (size_rounded[0], size_rounded[1]))
修复调整大小有助于防止缓冲区大小错误,因此不会导致垂直同步错误。
我有一个视频,我想使用 opencv 和 ffmpeg 进行剪切和裁剪。
我希望输出为 H265,因此我正在使用 ffmpeg 子进程(将帧字节写入标准输入),如
import os, shlex, subprocess, cv2, imutils
VIDEO_DIR = '../SoExample' # should contain a file 'in.mpg'
TIMESPAN = (3827, 3927) # cut to this timespan (frame numbers)
CROP = dict(min_x=560, max_x=731, min_y=232, max_y=418) # crop to this area
# calculate output video size
size = (CROP['max_x']-CROP['min_x'], CROP['max_y']-CROP['min_y']) # (w,h)
# ffmpeg throws an error when having odd dimensions that are not dividable by 2,
# so i just add a pixel to the size and stretch the original image by 1 pixel later.
size_rounded = (size[0]+1 if size[0] % 2 != 0 else size[0],
size[1]+1 if size[1] % 2 != 0 else size[1])
# read input video
vid_path_in = os.path.join(VIDEO_DIR, 'in.mpg')
cap = cv2.VideoCapture(vid_path_in)
fps = int(cap.get(cv2.CAP_PROP_FPS))
# generate and run ffmpeg command
ffmpeg_cmd = (f'/usr/bin/ffmpeg -y -s {size_rounded[0]}x{size_rounded[1]} -pixel_format'
+ f' bgr24 -f rawvideo -r {fps} -re -i pipe: -vcodec libx265 -pix_fmt yuv420p'
+ f' -crf 24 -x265-params "ctu=64" "{os.path.join(VIDEO_DIR, "out.mp4")}"')
print("using cmd", ffmpeg_cmd)
process = subprocess.Popen(shlex.split(ffmpeg_cmd), stdin=subprocess.PIPE)
# seek to the beginning of the cutting timespan and loop through frames of input video
cap.set(cv2.CAP_PROP_POS_FRAMES, TIMESPAN[0])
frame_returned = True
while cap.isOpened() and frame_returned:
frame_returned, frame = cap.read()
frame_number = cap.get(cv2.CAP_PROP_POS_FRAMES) - 1
# check if timespan end is not reached yet
if frame_number < TIMESPAN[1]:
# crop to relevant image area
frame_cropped = frame[CROP['min_y']:CROP['max_y'],
CROP['min_x']:CROP['max_x']]
# resize to even frame size if needed:
if size != size_rounded:
frame_cropped = imutils.resize(frame_cropped, width=size_rounded[0],
height=size_rounded[1])
# Show processed image using opencv: I see no errors here.
cv2.imshow('Frame', frame_cropped)
# Write cropped video frame to input stream of ffmpeg sub-process.
process.stdin.write(frame_cropped.tobytes())
else:
break
# Press Q on keyboard to exit earlier
if cv2.waitKey(25) & 0xFF == ord('q'):
break
process.stdin.close() # Close and flush stdin
process.wait() # Wait for sub-process to finish
process.terminate() # Terminate the sub-process
print("Done!")
不幸的是,我的输出是这样的:
输出不应包含此垂直滑动故障。有谁知道如何修复它?
上述脚本的控制台输出显示:
using cmd /usr/bin/ffmpeg -y -s 172x186 -pixel_format bgr24 -f rawvideo -r 23 -i pipe: -vcodec libx265 -pix_fmt yuv420p -crf 24 -x265-params "ctu=64" "../SoExample/out.mp4"
ffmpeg version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
WARNING: library configuration mismatch
avcodec configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, rawvideo, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: 17659 kb/s
Stream #0:0: Video: rawvideo (BGR[24] / 0x18524742), bgr24, 172x186, 17659 kb/s, 23 tbr, 23 tbn, 23 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (libx265))
x265 [info]: HEVC encoder version 2.6
x265 [info]: build info [Linux][GCC 7.2.0][64 bit] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
x265 [info]: Main profile, Level-2 (Main tier)
x265 [info]: Thread pool created using 4 threads
x265 [info]: Slices : 1
x265 [info]: frame threads / pool features : 2 / wpp(3 rows)
x265 [warning]: Source height < 720p; disabling lookahead-slices
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 2
x265 [info]: Keyframe min / max / scenecut / bias: 23 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0
x265 [info]: References / ref-limit cu / depth : 3 / on / on
x265 [info]: AQ: mode / str / qg-size / cu-tree : 1 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : CRF-24.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 rskip signhide tmvp strong-intra-smoothing
x265 [info]: tools: deblock sao
Output #0, mp4, to '../SoExample/out.mp4':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: hevc (libx265) (hev1 / 0x31766568), yuv420p, 172x186, q=2-31, 23 fps, 11776 tbn, 23 tbc
Metadata:
encoder : Lavc57.107.100 libx265
[rawvideo @ 0x564ebd221aa0] Invalid buffer size, packet size 51600 < expected frame_size 95976
Error while decoding stream #0:0: Invalid argument
frame= 100 fps= 30 q=-0.0 Lsize= 36kB time=00:00:04.21 bitrate= 69.1kbits/s speed=1.25x
video:32kB audio:0kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 12.141185%
x265 [info]: frame I: 1, Avg QP:22.44 kb/s: 179.77
x265 [info]: frame P: 29, Avg QP:24.20 kb/s: 130.12
x265 [info]: frame B: 70, Avg QP:29.99 kb/s: 27.82
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
x265 [info]: consecutive B-frames: 20.0% 3.3% 16.7% 43.3% 16.7%
encoded 100 frames in 3.35s (29.83 fps), 59.01 kb/s, Avg QP:28.23
Done!
如您所见,出现错误:Invalid buffer size, packet size 51600 < expected frame_size 95976 Error while decoding stream #0:0: Invalid argument
,您认为这可能是所显示问题的原因吗?我不确定,因为最后它告诉我所有 100 帧都会被编码。
如果您想在完全相同的视频上重现此内容,您可以在 UCF Aerial Action Dataset 中找到 actions1.mpg
。
非常感谢任何帮助,因为我真的被这个错误困住了。
修复错误比预期的要容易。
imutils.resize()
仅尝试评估宽度或高度参数,而不是两者,并尝试保留图像的原始纵横比,而 cv2.resize()
为您提供自由选择(w/o 任何约束) [Source Code, Explanation]
就我而言,这会导致意外的调整大小行为。我告诉 imutils
将我的 (171, 186)
图像调整为 (172, 186)
,但它所做的是调整为 (172, 187)
,因为它决定宁愿保持纵横比而不是想要的高度,所以它丢弃了我提交的高度。
简单的解决方法是替换
imutils.resize(frame_cropped, width=size_rounded[0], height=size_rounded[1])
来自
cv2.resize(frame_cropped, (size_rounded[0], size_rounded[1]))
修复调整大小有助于防止缓冲区大小错误,因此不会导致垂直同步错误。