FFMPEG дублирует первый кадр при кодировании

Использование ffprobe показывает, что оба видео имеют одинаковое количество кадров, но если я извлекаю кадры в виде изображений, сжатый имеет дополнительный кадр в начале (это просто дублированный первый кадр).

Это вызывает у меня много проблем, так как мне приходится вычислять разницу кадров между двумя видео, а наличие дополнительного кадра приводит к рассинхронизации.

Вход

ffmpeg -i "720p50_mobcal_ter.avi" -an -f mpeg2video -y "720p50_mobcal_ter.mpg"

Вывод

ffmpeg version N-76684-g1fe82ab Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
  libavutil      55.  6.100 / 55.  6.100
  libavcodec     57. 15.100 / 57. 15.100
  libavformat    57. 14.100 / 57. 14.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 15.100 /  6. 15.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, avi, from '720p50_mobcal_ter.avi':
  Metadata:
    encoder         : Lavf57.14.100
  Duration: 00:00:10.08, start: 0.000000, bitrate: 552974 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1280x720, 554059 kb/s, SAR 1:1 DAR 16:9, 50 fps, 50 tbr, 50 tbn, 50 tbc
Output #0, mpeg2video, to '720p50_mobcal_ter.mpg':
  Metadata:
    encoder         : Lavf57.14.100
    Stream #0:0: Video: mpeg2video, yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 50 fps, 50 tbn, 50 tbc
    Metadata:
      encoder         : Lavc57.15.100 mpeg2video
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> mpeg2video (native))
Press [q] to stop, [?] for help
frame=   41 fps=0.0 q=31.0 size=     984kB time=00:00:00.78 bitrate=10330.5kbits/frame=   80 fps= 78 q=31.0 size=    1323kB time=00:00:01.56 bitrate=6948.1kbits/frame=  124 fps= 80 q=31.0 size=    1725kB time=00:00:02.44 bitrate=5790.0kbits/frame=  168 fps= 81 q=31.0 size=    2084kB time=00:00:03.32 bitrate=5142.8kbits/frame=  212 fps= 81 q=31.0 size=    2482kB time=00:00:04.20 bitrate=4841.4kbits/frame=  255 fps= 82 q=31.0 size=    2840kB time=00:00:05.06 bitrate=4597.2kbits/frame=  296 fps= 82 q=31.0 size=    3133kB time=00:00:05.88 bitrate=4364.5kbits/frame=  338 fps= 82 q=24.8 size=    3453kB time=00:00:06.72 bitrate=4209.2kbits/frame=  382 fps= 82 q=31.0 size=    3723kB time=00:00:07.60 bitrate=4013.4kbits/frame=  426 fps= 83 q=31.0 size=    4005kB time=00:00:08.48 bitrate=3869.1kbits/frame=  470 fps= 83 q=24.8 size=    4276kB time=00:00:09.36 bitrate=3742.5kbits/frame=  504 fps= 83 q=31.0 Lsize=    4469kB time=00:00:10.06 bitrate=3639.3kbits/s
video:4469kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

Мое текущее решение состоит в том, чтобы обрезать сжатое видео перед вычислением различий, но это связано с повторным кодированием и потерей качества, что делает результаты бесполезными.

Чтобы сделать вопрос более полным, вот команды, которые я использую для обрезки и вычисления различий:

ffmpeg -y -i "720p50_mobcal_ter.mpg" -an -f mpeg2video -vf select=gte(n\,1) "cut-720p50_mobcal_ter.mpg"


ffmpeg -y -i "720p50_mobcal_ter.avi" -i "cut-720p50_mobcal_ter.mpg" -filter_complex "blend=all_mode=difference,hue=s=0" -c:v libx264 -crf 18 -c:a copy "differences.mpg"

Возникает вопрос: как избежать дублирования первого кадра? Если этого нельзя избежать, есть ли способ удалить его без повторного кодирования видео или просто пропустить его при вычислении различий?

РЕДАКТИРОВАТЬ:

Следуя ответу @Mulvya, я попробовал его предложение, но оно почему-то не работает. Я понимаю, что трудно найти проблему, не имея видеофайла, поэтому вместо этого я публикую скриншот с первыми 4 кадрами каждого видео, чтобы помочь вам визуализировать мою проблему.

введите описание изображения здесь

Как видите, сжатое видео имеет серый третий кадр, который портит различия.

Причина этого редактирования заключается в том, что я уверен, что данный ответ должен работать, по крайней мере, исходя из моего понимания того, как работают сопоставления фильтров, но, вероятно, он не работает, потому что проблема здесь не в том, что я думал.

Я ожидаю, что на видео различий будет почти черный третий кадр, а не полный кадр из исходного.

РЕДАКТИРОВАТЬ 2: Попробовал новое решение, которое каким-то образом сработало в первый раз, но теперь оно больше не работает.

Вот список команд, которые я использую, результат тот же, что и на снимке экрана, но теперь проблема переместилась на второй кадр вместо третьего (в основном это похоже на то, как был бы скриншот без 00000.png кадры)

ffmpeg  -i "720p50_mobcal_ter.avi" -an -f mpeg1video -y "compressed.mpg" 
ffmpeg  -i "720p50_mobcal_ter.avi" -vf fps=50 "original\image-%05d.png"
ffmpeg  -i "compressed.mpg" -vf fps=50 "compressed\image-%05d.png"
ffmpeg  -y -i "720p50_mobcal_ter.avi" -i "compressed.mpg" -filter_complex "[1:v]trim=start_frame=1,setpts=PTS-STARTPTS[cut];[0:v][cut]blend=all_mode=difference,hue=s=0" -c:v libx264 -crf 18 -c:a copy "differences.mpg" 
ffmpeg  -i "differences.mpg" -vf fps=50 "differences\image-%05d.png"

Исходное видео, которое я использую, находится здесь на случай, если вы захотите попробовать сами.

У меня тоже была эта проблема с последним двоичным файлом zeranoe. Решается с помощью фильтра fps для вывода.

Ответы (2)

Вы можете пропустить этот первый кадр в процессе вычисления.

ffmpeg -y -i "720p50_mobcal_ter.avi" -i "720p50_mobcal_ter.mpg" -filter_complex "[1:v]trim=start_frame=1,setpts=PTS-STARTPTS[cut];[0:v][cut]blend=all_mode=difference,hue=s=0" -c:v libx264 -crf 18 -c:a copy "differences.mpg"

Изменить : по запросу добавлены команды, которые я использовал для воспроизведения поведения, но у меня не возникло проблемы.

ffmpeg -i "720p50_mobcal_ter.y4m" -c:v copy "720p50_mobcal_ter.avi"
ffmpeg -i "720p50_mobcal_ter.avi" -c:v mpeg2video "720p50_mobcal_ter.mpg"
ffmpeg -i "720p50_mobcal_ter.avi" -i "720p50_mobcal_ter.mpg" -filter_complex blend=all_mode=difference,hue=s=0 -c:v libx264 -crf 18 "differences.mp4"

ffmpeg -i "720p50_mobcal_ter.avi" avi\frames%03d.png
ffmpeg -i "720p50_mobcal_ter.mpg" mpg\frames%03d.png

Моя сборка ffmpeg, взятая из Zeranoe

ffmpeg version N-77380-g2dba040 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
  libavutil      55. 11.100 / 55. 11.100
  libavcodec     57. 18.100 / 57. 18.100
  libavformat    57. 20.100 / 57. 20.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 21.100 /  6. 21.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Хотя я уверен, что ваш ответ правильный, по некоторым причинам он не сработал, и я обновил вопрос, чтобы предоставить более подробную информацию, которая может быть полезна.
Сбросьте PTS согласно отредактированной команде и проверьте.
Снова отредактировал OP, потому что у меня все еще есть проблемы.
Посмотрю исходное видео.
Не могу воспроизвести проблему. Здесь выровнены кадры. См. datafilehost.com/d/8b05aaaf
Какова ваша команда для создания AVI?
Прошло некоторое время, но я думаю, что использовал этот, ffmpeg -i input.y4m -an -vcodec rawvideo -y output.aviпотому что мне нужно, чтобы он был несжатым. Я не уверен, хотя, может быть, это поможет, если вы опубликуете команду, которую вы использовали для создания .avi.
ffmpeg -i input.y4m -c:v copy output.avi-- входной видеопоток уже является rawvideo, поэтому генерация AVI не требуется. Попробуйте более новую сборку ffmpeg.
Воссоздал AVI вашей командой и обновил до последней сборки, по-прежнему никаких отличий от предыдущих результатов. Не могли бы вы написать все команды, которые вы использовали, чтобы добраться до вашего видео различий? Может быть, что-то не так в том, как я сжимаю видео.
Я получаю идентичные результаты с перекодированием mpeg1video и сравниваю с mpeg2video.
Я понятия не имею, почему это происходит, но с вашей командой кодирования все работает нормально, поэтому я приму ваш ответ.

Я дополнительно проанализировал эту проблему и обнаружил, что она существует даже в версии 2.8.1 ffmpeg. Но на удивление первый кадр дублируется только при перекодировании входного видео с 23.976 fps!!! Когда я перекодирую видео с любым другим кадром в секунду (24, 25, 29,976, 30), начальные кадры выглядят нормально.