2016-07-22 4 views
1

Я кодирую 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-кодирования без этого большого начального кадра.

+0

Кажется, кодирование с помощью двухпроходного VBR позволяет избежать такого поведения. Хотя я бы предпочел использовать кодирование CRF для поддержания постоянного качества. –

+0

Константный тарифный коэффициент (CRF) будет корректировать QP для кадра в зависимости от того, что происходит в кадре - очень просто, когда есть небольшое действие или движение, оно уменьшит QP и выбросит больше, чтобы получить меньший пакет. Его в значительной степени по определению будет давать вам непостоянный размер кадра. Является ли ваш опыт предположением, что даже при условии, что это первый кадр, аномально большой? – Mick

+0

@ Мик, первый и второй кадры почти идентичны по содержанию, поэтому не должно быть причин иметь такую ​​разницу в QP. Хотя я, конечно, мог понять, что это всего лишь малая ошибка для алгоритма CRF, который не должен регулярно заботиться об этом первом первом кадре. –

ответ

1

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

ffmpeg -i test.mp4 -ss 0.016 -c copy test1.mp4 

Здесь значения сс < = 1/framerate. Поскольку это поток с внутренним кодированием, это точный раскол.

Смежные вопросы