FFMPEG 视频在不完美正方形时损坏
FFMPEG Video Corrupt When Not Perfect Square
我正在使用以下方法从 OpenCV 写入帧。这些代码在使用像 1000x1000 或 500x500 这样的完美正方形分辨率时工作得很好,但是当尝试使用 1920x1200 或任何其他矩形分辨率时,写入的 MP4 包含所附图像中看到的内容。 MP4 文件播放该静止帧的确切秒数。
什么可能导致这种行为?
- 相机宽高与输出分辨率匹配
- 附件中看到的实际上是相机的一帧画面,只是看到的方式被破坏了。
- 文件大小大致符合预期输出
process = sp.Popen(shlex.split(f'ffmpeg -y -hide_banner -loglevel error
-s {fwidth}x{fheight} -pixel_format bgr24 -f rawvideo
-r {self.fps} -i pipe: -vcodec libx265 -pix_fmt yuv420p
-crf 24 {filename}'), stdin=sp.PIPE)
for frame in frameList:
process.stdin.write(frame.tobytes())
# Close and flush stdin
process.stdin.close()
# Wait for sub-process to finish
process.wait()
# Terminate the sub-process
process.terminate()
附件是ffprobe日志
ffprobe version 3.4.8-0ubuntu0.2 Copyright (c) 2007-2020 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --prefix=/usr --extra-version=0ubuntu0.2 --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.2 --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, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/html/students/RH-PITCH_VIDEO.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf57.83.100
Duration: 00:00:03.13, start: 0.000000, bitrate: 452 kb/s
Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv, progressive), 1200x1100, 432 kb/s, 160 fps, 160 tbr, 10240 tbn, 160 tbc (default)
Metadata:
handler_name : VideoHandler
所描述的行为肯定表明以错误的顺序传输帧数据。
给定一个(行)连续的 numpy 数组(即 C-ordered 数组),np.uint8
RGB24/BGR24 帧应该被存储,所以 frame.shape = (height, width, ncomp=3)
。如果顺序不正确,请使用 np.transpose
对数组维度重新排序。
同时,FFmpeg 的大小输入选项被指定为-s widthxheight
。所以首先确保宽度和高度与框架形状匹配。
如果你的框架维度是正确的,那么你的 numpy 数组很可能是按 Fortran 顺序或列连续顺序格式化的。对于此表示,正确的形状是 ncomp x width x height
。将 height x width x ncomp
数组发送到 ffmpeg 的 stdin
管道也会破坏图像。为此,一个简单的解决方法是使用 frame.tobytes('C')
重新排序字节。
无论如何,最有效的方法是在上游解决尺寸问题,因此 frame
以正确的 FFmpeg 形状生成。
我正在使用以下方法从 OpenCV 写入帧。这些代码在使用像 1000x1000 或 500x500 这样的完美正方形分辨率时工作得很好,但是当尝试使用 1920x1200 或任何其他矩形分辨率时,写入的 MP4 包含所附图像中看到的内容。 MP4 文件播放该静止帧的确切秒数。
什么可能导致这种行为?
- 相机宽高与输出分辨率匹配
- 附件中看到的实际上是相机的一帧画面,只是看到的方式被破坏了。
- 文件大小大致符合预期输出
process = sp.Popen(shlex.split(f'ffmpeg -y -hide_banner -loglevel error
-s {fwidth}x{fheight} -pixel_format bgr24 -f rawvideo
-r {self.fps} -i pipe: -vcodec libx265 -pix_fmt yuv420p
-crf 24 {filename}'), stdin=sp.PIPE)
for frame in frameList:
process.stdin.write(frame.tobytes())
# Close and flush stdin
process.stdin.close()
# Wait for sub-process to finish
process.wait()
# Terminate the sub-process
process.terminate()
附件是ffprobe日志
ffprobe version 3.4.8-0ubuntu0.2 Copyright (c) 2007-2020 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --prefix=/usr --extra-version=0ubuntu0.2 --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.2 --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, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/html/students/RH-PITCH_VIDEO.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf57.83.100
Duration: 00:00:03.13, start: 0.000000, bitrate: 452 kb/s
Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv, progressive), 1200x1100, 432 kb/s, 160 fps, 160 tbr, 10240 tbn, 160 tbc (default)
Metadata:
handler_name : VideoHandler
所描述的行为肯定表明以错误的顺序传输帧数据。
给定一个(行)连续的 numpy 数组(即 C-ordered 数组),np.uint8
RGB24/BGR24 帧应该被存储,所以 frame.shape = (height, width, ncomp=3)
。如果顺序不正确,请使用 np.transpose
对数组维度重新排序。
同时,FFmpeg 的大小输入选项被指定为-s widthxheight
。所以首先确保宽度和高度与框架形状匹配。
如果你的框架维度是正确的,那么你的 numpy 数组很可能是按 Fortran 顺序或列连续顺序格式化的。对于此表示,正确的形状是 ncomp x width x height
。将 height x width x ncomp
数组发送到 ffmpeg 的 stdin
管道也会破坏图像。为此,一个简单的解决方法是使用 frame.tobytes('C')
重新排序字节。
无论如何,最有效的方法是在上游解决尺寸问题,因此 frame
以正确的 FFmpeg 形状生成。