FFmpeg 在 H264/TS 转为 RAW/AVI 后丢失帧

FFmpeg 在 H264/TS 转为 RAW/AVI 后丢失帧

使用以下方式将 H264/TS 转换为 RAW/AVI

ffmpeg -i in.ts -vcodec rawvideo -pix_fmt yuv420p out.avi

我发现输出的 AVI 文件的帧数比预期的要少。这可能是由于 TS 中的 PTS 错误造成的,但如果我使用该-vcodec copy选项先将其转换为 MP4,则在执行 MP4 到 RAW/AVI 转换时不会丢失帧。

有没有办法可以忽略 PTS 直接从 TS 转换?

原始 H264/TS 信息:

$ ffmpeg -i input.ts
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
  built on Jun  3 2013 03:49:16 with gcc 4.7.3 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
  libavutil      52. 34.100 / 52. 34.100
  libavcodec     55. 14.100 / 55. 14.100
  libavformat    55.  8.102 / 55.  8.102
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 74.101 /  3. 74.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
[mpegts @ 000000000248b440] max_analyze_duration 5000000 reached at 5000000 microseconds
Input #0, mpegts, from 'input.ts':
  Duration: 00:00:00.04, start: 1.400000, bitrate: N/A
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240, 24 fps, 24 tbr, 90k tbn, 48 tbc

FFMPEG 报告持续时间为 4 秒,速度为 24fps,但使用 TS 分析器我发现了 9598 帧,并且我看到了 PTS/DTS 错误。

如果我们直接转换为 AVI:

$ ffmpeg -i input.ts -vcodec rawvideo -pix_fmt yuv420p output.avi
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
  built on Jun  3 2013 03:49:16 with gcc 4.7.3 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
  libavutil      52. 34.100 / 52. 34.100
  libavcodec     55. 14.100 / 55. 14.100
  libavformat    55.  8.102 / 55.  8.102
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 74.101 /  3. 74.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
[mpegts @ 00000000025dbc80] max_analyze_duration 5000000 reached at 5000000 microseconds
Input #0, mpegts, from 'input.ts':
  Duration: 00:00:00.04, start: 1.400000, bitrate: N/A
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240, 24 fps, 24 tbr, 90k tbn, 48 tbc
Output #0, avi, to 'output.avi':
  Metadata:
    ISFT            : Lavf55.8.102
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, q=2-31, 200 kb/s, 24 tbn, 24 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (h264 -> rawvideo)
Press [q] to stop, [?] for help
frame= 3393 fps=1521 q=0.0 Lsize=  381798kB time=00:02:21.37 bitrate=22123.3kbits/s dup=0 drop=6207
video:381712kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.022287%

输出显示frame= 3393 现在我先将其转换为 MP4 ( -vcode copy) 然后再转换为 AVI

$ ffmpeg -i input.ts -vcodec copy output.mp4
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
  built on Jun  3 2013 03:49:16 with gcc 4.7.3 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
  libavutil      52. 34.100 / 52. 34.100
  libavcodec     55. 14.100 / 55. 14.100
  libavformat    55.  8.102 / 55.  8.102
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 74.101 /  3. 74.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
[mpegts @ 000000000248bb40] max_analyze_duration 5000000 reached at 5000000 microseconds
Input #0, mpegts, from 'input.ts':
  Duration: 00:00:00.04, start: 1.400000, bitrate: N/A
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240, 24 fps, 24 tbr, 90k tbn, 48 tbc
Output #0, mp4, to 'output.mp4':
  Metadata:
    encoder         : Lavf55.8.102
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 320x240, q=2-31, 24 fps, 90k tbn, 90k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 9600 fps=0.0 q=-1.0 Lsize=  105953kB time=00:06:39.95 bitrate=2170.1kbits/s
video:105838kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.108838%

我们看到了frame= 9600复制到 MP4 中并且 MP4 转换为 AVI 时具有正确数量的转码帧。我搜索了使用原始 TS 文件的命令以防止跳帧,因为使用中间转换作为 MP4 会消耗存储和时间!

$ ffmpeg -i output.mp4 -vcodec rawvideo -pix_fmt yuv420p output.avi
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
  built on Jun  3 2013 03:49:16 with gcc 4.7.3 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
  libavutil      52. 34.100 / 52. 34.100
  libavcodec     55. 14.100 / 55. 14.100
  libavformat    55.  8.102 / 55.  8.102
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 74.101 /  3. 74.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.8.102
  Duration: 00:06:40.00, start: 0.000000, bitrate: 2169 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 320x240, 2167 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc
    Metadata:
      handler_name    : VideoHandler
File 'output.avi' already exists. Overwrite ? [y/N] y
Output #0, avi, to 'output.avi':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    ISFT            : Lavf55.8.102
    Stream #0:0(und): Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, q=2-31, 200 kb/s, 24 tbn, 24 tbc
    Metadata:
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 -> rawvideo)
Press [q] to stop, [?] for help
frame= 9600 fps=4491 q=0.0 Lsize= 1080301kB time=00:06:40.00 bitrate=22124.6kbits/s
video:1080000kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.027894%

相关内容