Я кодирую h264 mp4 и имею небольшую проблему с размером выходного байта первого кадра по сравнению со всеми другими кадрами. Существует не дублирование кадров, а просто, что первый кадр всегда заканчивается ~ 2x размером байта других кадров. Мой случай использования требует, чтобы первый кадр был очень похож по размеру по сравнению с другим фреймом.Размер кадра первого кадра FFmpeg по сравнению со всеми другими кадрами - с 100% ключевыми кадрами
Вот параметры кодирования FFmpeg:
ffmpeg -framerate 60 -i "C:\Test%4d.jpg" -c:v libx264 -g 1 -vf "scale=3840:2160" -crf 19 -pix_fmt yuv420p C:\Test.mp4
и детали рамы с помощью ffprobe:
ffprobe C:\Test.mp4 -show_frames -of compact -show_entries frame=pict_type,pkt_size
ffprobe version N-79143-g8ff0f6a Copyright (c) 2007-2016 the FFmpeg developers
built with gcc 5.3.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-libmfx --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --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. 19.100/55. 19.100
libavcodec 57. 30.100/57. 30.100
libavformat 57. 29.101/57. 29.101
libavdevice 57. 0.101/57. 0.101
libavfilter 6. 40.102/6. 40.102
libswscale 4. 0.100/4. 0.100
libswresample 2. 0.101/2. 0.101
libpostproc 54. 0.100/54. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\users\dusti\downloads\Test.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.29.101
Duration: 00:00:00.17, start: 0.000000, bitrate: 240225 kb/s
Stream #0:0(und): Video: h264 (High) (avc1/0x31637661), yuv420p, 3840x2160 [SAR 9:16 DAR 1:1], 240662 kb/s, 60 fps, 60 tbr, 15360 tbn, 120 tbc (default)
Metadata:
handler_name : VideoHandler
frame|pkt_size=1377043|pict_type=I
frame|pkt_size=406953|pict_type=I
frame|pkt_size=407200|pict_type=I
frame|pkt_size=406647|pict_type=I
frame|pkt_size=405276|pict_type=I
frame|pkt_size=404715|pict_type=I
frame|pkt_size=403226|pict_type=I
frame|pkt_size=401806|pict_type=I
frame|pkt_size=400750|pict_type=I
frame|pkt_size=400189|pict_type=I
Я подтвердил, что это проблема не только отчетность с ffprobe путем преобразования файла с mp4box:
mp4box.exe -dash 16.666 -frag 16.666 -rap c:\Test.mp4
который возвращает файл MPD:
<Initialization range="0-922"/>
<SegmentURL mediaRange="923-1378146" indexRange="923-966"/>
<SegmentURL mediaRange="1378147-1785280" indexRange="1378147-1378190"/>
<SegmentURL mediaRange="1785281-2192661" indexRange="1785281-1785324"/>
<SegmentURL mediaRange="2192662-2599489" indexRange="2192662-2192705"/>
<SegmentURL mediaRange="2599490-3004946" indexRange="2599490-2599533"/>
<SegmentURL mediaRange="3004947-3409842" indexRange="3004947-3004990"/>
<SegmentURL mediaRange="3409843-3813249" indexRange="3409843-3409886"/>
<SegmentURL mediaRange="3813250-4215236" indexRange="3813250-3813293"/>
<SegmentURL mediaRange="4215237-4616167" indexRange="4215237-4215280"/>
<SegmentURL mediaRange="4616168-5016537" indexRange="4616168-4616211"/>
</SegmentList>
Я пробовал кодировать фиктивный черный кадр, и, похоже, он работает вокруг проблемы, но я бы предпочел не делать этого. Вот размеры рамы с первым кадром заменяются чисто черной рамкой:
frame|pkt_size=2173|pict_type=I
frame|pkt_size=466255|pict_type=I
frame|pkt_size=430179|pict_type=I
frame|pkt_size=416652|pict_type=I
frame|pkt_size=411401|pict_type=I
frame|pkt_size=407174|pict_type=I
frame|pkt_size=405377|pict_type=I
frame|pkt_size=403207|pict_type=I
frame|pkt_size=401588|pict_type=I
frame|pkt_size=401200|pict_type=I
Кто-нибудь есть какие-либо подсказки о том, как контролировать это поведение? Я предполагаю, что это может иметь какое-то отношение к алгоритму качества CRF, но на самом деле понятия не имеет. Любая помощь будет оценена по достоинству.
Спасибо, Дастин
Update 7/22/16 После немного больше копать, я могу видеть, что FFmpeg использует более низкую QP для первого кадра:
[libx264 @ 05380b60] frame= 0 QP=14.92 NAL=3 Slice:I Poc:0 I:32400 P:0 SKIP:0 size=1485053 bytes
[libx264 @ 05380b60] frame= 1 QP=29.48 NAL=3 Slice:I Poc:0 I:32400 P:0 SKIP:0 size=361196 bytes
[libx264 @ 05380b60] frame= 2 QP=29.48 NAL=3 Slice:I Poc:0 I:32400 P:0 SKIP:0 size=359406 bytes
Но я до сих пор не найдено способа избежать такого поведения. Я попытался установить qpmin/qpmax на значения, отличные от значений по умолчанию, но это ничего не изменило. В моем комментарии ниже двухпроходное кодирование не проявляет такого поведения. Все еще ищут способ использования CRF-кодирования без этого большого начального кадра.
Кажется, кодирование с помощью двухпроходного VBR позволяет избежать такого поведения. Хотя я бы предпочел использовать кодирование CRF для поддержания постоянного качества. –
Константный тарифный коэффициент (CRF) будет корректировать QP для кадра в зависимости от того, что происходит в кадре - очень просто, когда есть небольшое действие или движение, оно уменьшит QP и выбросит больше, чтобы получить меньший пакет. Его в значительной степени по определению будет давать вам непостоянный размер кадра. Является ли ваш опыт предположением, что даже при условии, что это первый кадр, аномально большой? – Mick
@ Мик, первый и второй кадры почти идентичны по содержанию, поэтому не должно быть причин иметь такую разницу в QP. Хотя я, конечно, мог понять, что это всего лишь малая ошибка для алгоритма CRF, который не должен регулярно заботиться об этом первом первом кадре. –