ffmpeg 在 rawvideo AVI 格式中的扫描线排序

ffmpeg 在 rawvideo AVI 格式中的扫描线排序

我正在使用 ffmpeg 将视频转码为特定的 AVI 格式ffmpeg.exe -i "Input.ext" -y -vcodec rawvideo -pix_fmt rgb555le -an -map_metadata -1 TEST_ENCODE.avi。生成的 AVI 是不再支持的旧命令行程序的输入。不幸的是,尽管格式正确并使用了正确的编码,但该程序无法读取由 ffmpeg 生成的 AVI。经过几天的分析和调试,我终于确定了问题所在。ffmpeg 使用负高度对 AVI 中的位图帧进行编码,表示自上而下的扫描线顺序。但我的其他程序需要正高度和更传统的自下而上的扫描线顺序。是否可以强制 ffmpeg 对帧使用正高度(自下而上的扫描线顺序)?

编辑:即使将详细程度调高到尽可能高,我仍然无法让 ffmpeg 报告足够的细节来捕捉编码中这个通常不重要的细节,但由于我被要求提供日志,我会提供它们。

在旧版应用程序中工作:

D:\AutoHotkey Scripts\PS Gui v4\!OutputDest>"D:\Program Files\ffmpeg\bin\ffmpeg.exe" -v 9 -loglevel 99 -i TEST_COPY.avi
ffmpeg version git-2020-06-17-0b3bd00 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.3.1 (GCC) 20200523
  configuration: --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 --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. 55.100 / 56. 55.100
  libavcodec     58. 92.100 / 58. 92.100
  libavformat    58. 46.101 / 58. 46.101
  libavdevice    58. 11.100 / 58. 11.100
  libavfilter     7. 86.100 /  7. 86.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set logging level) with argument '9'.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument '99'.
Reading option '-i' ... matched as input url with argument 'TEST_COPY.avi'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set logging level) with argument 9.
Successfully parsed a group of options.
Parsing a group of options: input url TEST_COPY.avi.
Successfully parsed a group of options.
Opening an input file: TEST_COPY.avi.
[NULL @ 000002d12df7bf80] Opening 'TEST_COPY.avi' for reading
[file @ 000002d12df7c880] Setting default whitelist 'file,crypto,data'
Probing avi score:100 size:2048
[avi @ 000002d12df7bf80] Format avi probed with size=2048 and score=100
[avi @ 000002d12df7d300] use odml:1
[avi @ 000002d12df7bf80] pos:14 tag: tag=LIST size=0x11ec
[avi @ 000002d12df7bf80] pos:18 list: tag=hdrl size=0x0
[avi @ 000002d12df7bf80] pos:20 tag: tag=avih size=0x38
[avi @ 000002d12df7bf80] pos:60 tag: tag=LIST size=0x1094
[avi @ 000002d12df7bf80] pos:64 list: tag=strl size=0x0
[avi @ 000002d12df7bf80] pos:6C tag: tag=strh size=0x38
[avi @ 000002d12df7bf80] pos:74 strh: tag=vids size=0xffffffff
[avi @ 000002d12df7bf80] 125000 8341 0
[avi @ 000002d12df7bf80] pos:AC tag: tag=strf size=0x28
[avi @ 000002d12df7bf80] pos:D4 video: tag=[0][0][0][0] size=0x0
[avi @ 000002d12df7bf80] pos:DC tag: tag=JUNK size=0x1018
[avi @ 000002d12df7bf80] pos:10FC tag: tag=JUNK size=0x104
[avi @ 000002d12df7bf80] pos:1208 tag: tag=LIST size=0x1a
[avi @ 000002d12df7bf80] pos:120C list: tag=INFO size=0x0
[avi @ 000002d12df7bf80] pos:122A tag: tag=JUNK size=0x3f8
[avi @ 000002d12df7bf80] pos:162A tag: tag=LIST size=0x4268644
[avi @ 000002d12df7bf80] pos:162E list: tag=movi size=0x0
[avi @ 000002d12df7bf80] movi end=4269c6e
[avi @ 000002d12df7bf80] movi_end=0x4269c6e
[avi @ 000002d12df7bf80] 0: tag=0x63643030 flags=0x10 pos=0x4 len=348160/348160 cum_len=0
[avi @ 000002d12df7bf80] 1: tag=0x63643030 flags=0x10 pos=0x5500c len=348160/348160 cum_len=1
[avi @ 000002d12df7bf80] 2: tag=0x63643030 flags=0x10 pos=0xaa014 len=348160/348160 cum_len=2
[A bunch more of these, truncated due to size.]
[avi @ 000002d12df7bf80] 198: tag=0x63643030 flags=0x10 pos=0x41be634 len=348160/348160 cum_len=198
[avi @ 000002d12df7bf80] 199: tag=0x63643030 flags=0x10 pos=0x421363c len=348160/348160 cum_len=199
[avi @ 000002d12df7bf80] Before avformat_find_stream_info() pos: 5678 bytes read:104712 seeks:4 nb_streams:1
[avi @ 000002d12df7bf80] parser not found for codec rawvideo, packets or times may be invalid.
    Last message repeated 1 times
[avi @ 000002d12df7bf80] All info found
[avi @ 000002d12df7bf80] stream 0: start_time: 0 duration: 13.3456
[avi @ 000002d12df7bf80] format: start_time: 0 duration: 13.3456 (estimate from stream) bitrate=41747 kb/s
[avi @ 000002d12df7bf80] After avformat_find_stream_info() pos: 353846 bytes read:420112 seeks:4 frames:1
Input #0, avi, from 'TEST_COPY.avi':
  Metadata:
    encoder         : Lavf58.46.101
  Duration: 00:00:13.35, start: 0.000000, bitrate: 41747 kb/s
    Stream #0:0, 1, 8341/125000: Video: rawvideo, 1 reference frame, rgb555le, 640x272, 0/1, 41950 kb/s, 14.99 fps, 14.99 tbr, 14.99 tbn, 14.99 tbc
Successfully opened the file.
At least one output file must be specified
[AVIOContext @ 000002d12df85340] Statistics: 420112 bytes read, 4 seeks

TEST_ENCODE(不起作用):

D:\AutoHotkey Scripts\PS Gui v4\!OutputDest>"D:\Program Files\ffmpeg\bin\ffmpeg.exe" -v 9 -loglevel 99 -i TEST_ENCODE.avi
ffmpeg version git-2020-06-17-0b3bd00 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.3.1 (GCC) 20200523
  configuration: --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 --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. 55.100 / 56. 55.100
  libavcodec     58. 92.100 / 58. 92.100
  libavformat    58. 46.101 / 58. 46.101
  libavdevice    58. 11.100 / 58. 11.100
  libavfilter     7. 86.100 /  7. 86.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set logging level) with argument '9'.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument '99'.
Reading option '-i' ... matched as input url with argument 'TEST_ENCODE.avi'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set logging level) with argument 9.
Successfully parsed a group of options.
Parsing a group of options: input url TEST_ENCODE.avi.
Successfully parsed a group of options.
Opening an input file: TEST_ENCODE.avi.
[NULL @ 000002c07a68bf80] Opening 'TEST_ENCODE.avi' for reading
[file @ 000002c07a68c880] Setting default whitelist 'file,crypto,data'
Probing avi score:100 size:2048
[avi @ 000002c07a68bf80] Format avi probed with size=2048 and score=100
[avi @ 000002c07a68d300] use odml:1
[avi @ 000002c07a68bf80] pos:14 tag: tag=LIST size=0x11ec
[avi @ 000002c07a68bf80] pos:18 list: tag=hdrl size=0x0
[avi @ 000002c07a68bf80] pos:20 tag: tag=avih size=0x38
[avi @ 000002c07a68bf80] pos:60 tag: tag=LIST size=0x1094
[avi @ 000002c07a68bf80] pos:64 list: tag=strl size=0x0
[avi @ 000002c07a68bf80] pos:6C tag: tag=strh size=0x38
[avi @ 000002c07a68bf80] pos:74 strh: tag=vids size=0xffffffff
[avi @ 000002c07a68bf80] 125000 8341 0
[avi @ 000002c07a68bf80] pos:AC tag: tag=strf size=0x28
[avi @ 000002c07a68bf80] pos:D4 video: tag=[0][0][0][0] size=0x0
[avi @ 000002c07a68bf80] pos:DC tag: tag=JUNK size=0x1018
[avi @ 000002c07a68bf80] pos:10FC tag: tag=JUNK size=0x104
[avi @ 000002c07a68bf80] pos:1208 tag: tag=LIST size=0x1a
[avi @ 000002c07a68bf80] pos:120C list: tag=INFO size=0x0
[avi @ 000002c07a68bf80] pos:122A tag: tag=JUNK size=0x3f8
[avi @ 000002c07a68bf80] pos:162A tag: tag=LIST size=0x4268644
[avi @ 000002c07a68bf80] pos:162E list: tag=movi size=0x0
[avi @ 000002c07a68bf80] movi end=4269c6e
[avi @ 000002c07a68bf80] movi_end=0x4269c6e
[avi @ 000002c07a68bf80] 0: tag=0x63643030 flags=0x10 pos=0x4 len=348160/348160 cum_len=0
[avi @ 000002c07a68bf80] 1: tag=0x63643030 flags=0x10 pos=0x5500c len=348160/348160 cum_len=1
[avi @ 000002c07a68bf80] 2: tag=0x63643030 flags=0x10 pos=0xaa014 len=348160/348160 cum_len=2
[A bunch more of these, truncated due to size.]
[avi @ 000002c07a68bf80] 198: tag=0x63643030 flags=0x10 pos=0x41be634 len=348160/348160 cum_len=198
[avi @ 000002c07a68bf80] 199: tag=0x63643030 flags=0x10 pos=0x421363c len=348160/348160 cum_len=199
[avi @ 000002c07a68bf80] Before avformat_find_stream_info() pos: 5678 bytes read:104712 seeks:4 nb_streams:1
[avi @ 000002c07a68bf80] parser not found for codec rawvideo, packets or times may be invalid.
    Last message repeated 1 times
[avi @ 000002c07a68bf80] All info found
[avi @ 000002c07a68bf80] stream 0: start_time: 0 duration: 13.3456
[avi @ 000002c07a68bf80] format: start_time: 0 duration: 13.3456 (estimate from stream) bitrate=41747 kb/s
[avi @ 000002c07a68bf80] After avformat_find_stream_info() pos: 353846 bytes read:420112 seeks:4 frames:1
Input #0, avi, from 'TEST_ENCODE.avi':
  Metadata:
    encoder         : Lavf58.46.101
  Duration: 00:00:13.35, start: 0.000000, bitrate: 41747 kb/s
    Stream #0:0, 1, 8341/125000: Video: rawvideo, 1 reference frame, rgb555le, 640x272, 0/1, 41950 kb/s, 14.99 fps, 14.99 tbr, 14.99 tbn, 14.99 tbc
Successfully opened the file.
At least one output file must be specified
[AVIOContext @ 000002c07a695340] Statistics: 420112 bytes read, 4 seeks

如您所见,ffmpeg 加载了“strf”块,但没有报告位图标头中每个字段的内容。为了获取该信息,我找到了一个名为 VidTrace 的漂亮小程序(http://www.jmcgowan.com/aviauthor.html#VidTrace

在旧版应用程序中工作:

D:\AutoHotkey Scripts\PS Gui v4\!OutputDest>vidtrace.exe TEST_COPY.avi
RIFF (69642478) AVI
 LIST (4588) hdrl
  avih (56)
   Microseconds Per Frame: 66728
    14.986213 Frames Per Second
   Maximum Bytes Per Second: 5243818
   Pad to Multiples of This Size: 0
   Flags DWORD (hex): 910
    FLAG: (AVIF_HASINDEX)  AVI File Has 'idx1' chunk
    FLAG: (AVIF_ISINTERLEAVED)  AVI File is Interleaved
    FLAG: (AVIF_TRUSTCKTYPE)  Use Chunk Type to Find Key Frames
   Total Frames: 200
   Initial Frames: 0
   Number of Streams: 1
   Suggested Buffer Size: 1048576
   Width in Pixels: 640
   Height in Pixels: 272
   Scale (MAY BE UNUSED): 0
   Rate (MAY BE UNUSED): 0
    Samples Per Second (MAY BE UNUSED): 0
   Start of AVI File (MAY BE UNUSED): 0
   Length of AVI File (MAY BE UNUSED): 0
  LIST (4244) strl
   strh (56)
    Stream Type (Four Character Code): 'vids'
     'vids' is Four Character Code for Video Stream
    Installable Compressor (Four Character Code): ''
     '' is Four Character Code for Uncompressed DIB
    Flags (hex): 0
    Priority (MAY BE UNUSED) (hex): 0
    Language Code (MAY BE UNUSED) (hex): 0
    Initial Frames: 0
    Scale: 8341
    Rate: 125000
    Start: 0
    Length: 200
    Suggested Buffer Size: 348160
    Quality: 4294967295
    Sample Size: 0
    Frame - 16 bit RECT takes 8 bytes (MAY BE UNUSED): Top: 0 Bottom: 272 Left: 0 Right: 640
    Note on Frame: In 16 bit Windows, the RECT structure is
    Note on Frame: four (4) 16 bit integers, a total of 8 bytes.
    Note on Frame: Some AVI use a 16 bit RECT for Frame.
    Note on Frame: Others use a 32 bit RECT, a total of 16 bytes.
   strf (40)
    Windows Bitmap Header
    Number of Bytes Required by Bitmap Structure: 40
    Width of Bitmap in Pixels: 640
    Height of Bitmap in Pixels: 272
    Number of Planes: 1
    Number of Bits Per Pixel (1,4,8,16,24, or 32): 16
    Compression Mode (hex): 0
     COMPRESSION: Uncompressed RGB Format
    Size of Image in Bytes: 348160
    Horizontal Resolution in Pixels per Meter: 0
    Vertical Resolution in Pixels per Meter: 0
    Number of Color Indices Actually Used by the Bitmap: 0
    Number of Color Indices Considered Important to Display Bitmap: 0
   JUNK (4120)
  JUNK (260)
 LIST (26) INFO
  ISFT (14)
 JUNK (1016)
 LIST (69633604) movi
  00dc (348160)
  00dc (348160)
  00dc (348160)
  00dc (348160)
  [A bunch more of these, truncated due to size.]
  00dc (348160)
 idx1 (3200)

TEST_ENCODE(不起作用):

D:\AutoHotkey Scripts\PS Gui v4\!OutputDest>vidtrace.exe TEST_ENCODE.avi
RIFF (69642478) AVI
 LIST (4588) hdrl
  avih (56)
   Microseconds Per Frame: 66728
    14.986213 Frames Per Second
   Maximum Bytes Per Second: 4891499
   Pad to Multiples of This Size: 0
   Flags DWORD (hex): 910
    FLAG: (AVIF_HASINDEX)  AVI File Has 'idx1' chunk
    FLAG: (AVIF_ISINTERLEAVED)  AVI File is Interleaved
    FLAG: (AVIF_TRUSTCKTYPE)  Use Chunk Type to Find Key Frames
   Total Frames: 200
   Initial Frames: 0
   Number of Streams: 1
   Suggested Buffer Size: 1048576
   Width in Pixels: 640
   Height in Pixels: 272
   Scale (MAY BE UNUSED): 0
   Rate (MAY BE UNUSED): 0
    Samples Per Second (MAY BE UNUSED): 0
   Start of AVI File (MAY BE UNUSED): 0
   Length of AVI File (MAY BE UNUSED): 0
  LIST (4244) strl
   strh (56)
    Stream Type (Four Character Code): 'vids'
     'vids' is Four Character Code for Video Stream
    Installable Compressor (Four Character Code): ''
     '' is Four Character Code for Uncompressed DIB
    Flags (hex): 0
    Priority (MAY BE UNUSED) (hex): 0
    Language Code (MAY BE UNUSED) (hex): 0
    Initial Frames: 0
    Scale: 8341
    Rate: 125000
    Start: 0
    Length: 200
    Suggested Buffer Size: 348160
    Quality: 4294967295
    Sample Size: 0
    Frame - 16 bit RECT takes 8 bytes (MAY BE UNUSED): Top: 0 Bottom: 272 Left: 0 Right: 640
    Note on Frame: In 16 bit Windows, the RECT structure is
    Note on Frame: four (4) 16 bit integers, a total of 8 bytes.
    Note on Frame: Some AVI use a 16 bit RECT for Frame.
    Note on Frame: Others use a 32 bit RECT, a total of 16 bytes.
   strf (40)
    Windows Bitmap Header
    Number of Bytes Required by Bitmap Structure: 40
    Width of Bitmap in Pixels: 640
    Height of Bitmap in Pixels: -272
    Number of Planes: 1
    Number of Bits Per Pixel (1,4,8,16,24, or 32): 16
    Compression Mode (hex): 0
     COMPRESSION: Uncompressed RGB Format
    Size of Image in Bytes: 348160
    Horizontal Resolution in Pixels per Meter: 0
    Vertical Resolution in Pixels per Meter: 0
    Number of Color Indices Actually Used by the Bitmap: 0
    Number of Color Indices Considered Important to Display Bitmap: 0
   JUNK (4120)
  JUNK (260)
 LIST (26) INFO
  ISFT (14)
 JUNK (1016)
 LIST (69633604) movi
  00dc (348160)
  00dc (348160)
  00dc (348160)
  00dc (348160)
  [A bunch more of these, truncated due to size.]
  00dc (348160)
 idx1 (3200)

请注意“strf”块中“以像素为单位的位图高度”值的不同符号。

-vf vflip在编码时向 ffmpeg 添加了反转扫描线的功能,然后使用十六进制编辑器手动将位图高度编辑为正值。执行此操作后,我的旧程序可以正常运行,这证明负高度是导致我出现问题的唯一原因。

答案1

ffmpeg 需要更新才能生成具有正高度和自下而上扫描线顺序的 rawvideo AVI 视频帧。解决方案现在是使用命令-vf vflip -flipped_raw_rgb 1

相关内容