Який правильний спосіб виправити ключові кадри у FFmpeg для DASH?


38

Під час кондиціонування потоку для відтворення DASH випадкові точки доступу повинні бути точно в той самий час потоку джерела у всіх потоках. Звичайний спосіб зробити це - форсувати фіксовану частоту кадрів і фіксовану довжину GOP (тобто ключовий кадр кожні N кадрів).

У FFmpeg фіксована частота кадрів проста (-р НОМЕР).

Але для фіксованих ключових кадрів (довжина GOP) існують три методи ... який з них "правильний"? Документація FFmpeg з цього приводу неприємно розпливається.

Спосіб 1: возитися з аргументами libx264

-c:v libx264 -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE:scenecut=-1

Здається, виникають певні дискусії щодо того, чи слід вимкнути сценаркут чи ні, так як незрозуміло, чи буде перезапущено "лічильник" ключових кадрів, коли трапиться зріз сцени.

Спосіб 2: встановлення фіксованого розміру GOP:

-g GOP_LEN_IN_FRAMES

Це, на жаль, лише задокументоване при передачі документації FFMPEG, і, отже, ефект цього аргументу дуже неясний.

Спосіб 3: вставляйте ключовий кадр кожні N секунд ( можливо? ):

-force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)

Це є явним чином задокументовано. Але досі не зрозуміло, чи «лічильник часу» перезапуститься після кожного ключового кадру. Наприклад, якщо очікується 5-секундний GOP, якщо scenecutключовий кадр введений 3 секунди в libx264, чи буде наступний ключовий кадр через 5 секунд або через 2 секунди?

Насправді документація FFmpeg розрізняє це і -gваріант, але насправді не сказано, наскільки ці два варіанти вище є найменш різними (очевидно, -gбуде потрібно фіксована частота кадрів).

Що правильно?

Здавалося б, це -force_key_framesбуде вищим , оскільки це не вимагатиме фіксованої частоти кадрів. Однак це вимагає цього

  • він відповідає специфікаціям GOP у H.264 (за наявності )
  • Гарантує, що в фіксованій каденції буде ключовий кадр, незалежно від scenecutключових кадрів libx264 .

Здавалося б, це -gне може працювати без примусової фіксованої частоти кадрів ( -r) , оскільки немає гарантії, що кілька запусків ffmpegз різними аргументами кодека забезпечать однакову миттєву частоту кадрів у кожній роздільній здатності. Фіксована частота кадрів може знизити продуктивність стиснення (ВАЖЛИВО за сценарієм DASH!).

Нарешті, метод тільки здається , як зламати . Я сподіваюся проти надії, що це не правильна відповідь.keyint

Список літератури:

Приклад використання -force_key_framesметоду

Приклад використання keyintметоду

Розділ про додаткові параметри відео FFmpeg

Відповіді:


27

TL; DR

Я рекомендую наступне:

  • libx264: (і необов’язково додати )-g X -keyint_min X-force_key_frames "expr:gte(t,n_forced*N)"
  • libx265: -x265-params "keyint=X:min-keyint=X"
  • libvpx-vp9: -g X

де Xінтервал у кадрах і Nінтервал у секундах. Наприклад, для 2-секундного інтервалу з відео 30 кадрів в секунду X= 60 і N= 2.

Примітка про різні типи кадру

Щоб правильно пояснити цю тему, спершу треба визначити два типи I-кадри / ключові кадри:

  • Кадри миттєвого оновлення декодера (IDR): Вони дозволяють незалежне декодування наступних кадрів, без доступу до кадрів, попередніх до кадру IDR.
  • Кадри без IDR: для роботи декодування потрібен попередній кадр IDR. Кадри без IDR можна використовувати для вирізання сцени посеред GOP (група малюнків).

Що рекомендується для потокової передачі?

Для випадку передачі даних потрібно:

  • Переконайтесь, що всі кадри IDR знаходяться у регулярних положеннях (наприклад, за 2, 4, 6,… секунди), щоб відео можна було розділити на сегменти однакової довжини.
  • Увімкніть виявлення вирізання сцени, щоб поліпшити ефективність / якість кодування. Це означає, що I-кадри дозволяють розміщувати між кадрами IDR. Ви все ще можете працювати з вимкненим виявленням зрізів сцени (і це все ще є частиною посібників), але це не обов'язково.

Що роблять параметри?

Для того, щоб налаштувати кодер, ми повинні зрозуміти, що роблять параметри ключових кадрів. Я зробив кілька тестів і виявив наступне, для трьох датчиків libx264, libx265і libvpx-vp9в FFmpeg:

  • libx264:

    • -g встановлює інтервал ключових кадрів.
    • -keyint_min встановлює мінімальний інтервал ключових кадрів.
    • -x264-params "keyint=x:min-keyint=y"те саме, що -g x -keyint_min y.
    • Примітка. При встановленні обох на одне і те ж значення мінімум встановлюється внутрішньо на половину максимального інтервалу плюс один, як це видно в x264коді:

      h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
      
  • libx265:

    • -g не реалізовано.
    • -x265-params "keyint=x:min-keyint=y" працює.
  • libvpx-vp9:

    • -g встановлює інтервал ключових кадрів.
    • -keyint_min встановлює мінімальний інтервал ключових кадрів
    • Примітка. Завдяки тому, як працює FFmpeg, -keyint_minвін передається в кодер лише тоді, коли він такий самий, як -g. У коді з libvpxenc.cFFmpeg ми можемо знайти:

      if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
          enccfg.kf_min_dist = avctx->keyint_min;
      if (avctx->gop_size >= 0)
          enccfg.kf_max_dist = avctx->gop_size;
      

      Це може бути помилка (чи відсутність функції?), Оскільки libvpxнапевно підтримує встановлення іншого значення для kf_min_dist.

Чи варто використовувати -force_key_frames?

-force_key_framesПараметр примусово вводить ключові кадри на заданому інтервалі (вираз). Це працює для всіх кодерів, але це може зіпсуватись із механізмом контролю швидкості. Спеціально для VP9 я помітив сильні коливання якості, тому не можу рекомендувати використовувати його в цьому випадку.


Дякую! Це чудовий відгук. У мене є одне питання, як ви створили цю дивовижну таблицю. Я міг би повністю використовувати щось подібне.
Марк Героліматос

(Здається, немає ніякого способу написати вам безпосередньо) Чи можете ви, будь ласка, вказати мені на посилання на будь-які теми в цій дискусії МСЕ-T? Спасибі!
Марк Героліматос

2
Я тільки що зробив , що в Excel, вставивши вихід я отримав від трьох прогонів ffprobe -i input.mp4 -select_streams v -show_frames -of csv -show_entries frame=pict_type, потім фарбування клітин. Боюся, немає публічних дискусій, але я побачу, чи зможу викопати деякі з посилань, які я знайшов тоді.
slhck

Чи можете ви повторно спробувати експеримент із -force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)формою? Я просто спробував це і виявив, що, хоча в потоці були зайві I кадри, він, схоже, дотримується мого правила. Програма PERL буде "відповідь", оскільки ви не можете використовувати розмітку в коментарях.
Марк Героліматос

Цікаво. Я вважаю, що варто окремої "реальної" відповіді, якщо ви дізналися, що це працює. (Сайти для обміну стеками не дуже підходять для відповіді в стилі дискусії.) Останній раз, коли я перевірив, -force_key_framesне працював для мене, і тому я ніколи не намагався його повторити. Це було більше року тому. Можливо, це була помилка. Я скоро спробую знову.
slhck

12

Ось мої п’ятдесят центів за справу.

Спосіб 1:

возитися з аргументами libx264

-c: v libx264 -x264opts keyint = GOPSIZE: min-keyint = GOPSIZE: scenecut = -1

Створюйте рамки кадрів лише через потрібні інтервали.

Приклад 1:

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-x264opts "keyint=48:min-keyint=48:no-scenecut" \
-c:a copy \
-y test_keyint_48.mp4

Створіть рамки ifram, як очікувалося так:

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
961         40
1009        42
1057        44
1105        46
1153        48
1201        50
1249        52
1297        54
1345        56
1393        58

Спосіб 2 амортизується. Пропущено.

Спосіб 3:

вставляйте ключовий кадр кожні N секунд (МОЖЕ):

-force_key_frames expr: gte (t, n_forced * GOP_LEN_IN_SECONDS)

Приклад 2

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-force_key_frames "expr:gte(t,n_forced*2)"
-c:a copy \
-y test_fkf_2.mp4

Створіть рамки кадрів дещо по-іншому:

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
519         21.58333333
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
931         38.75
941         39.16666667
961         40
1008        42
1056        44
1104        46
1152        48
1200        50
1248        52
1296        54
1305        54.375
1344        56
1367        56.95833333
1392        58
1430        59.58333333
1440        60
1475        61.45833333
1488        62
1536        64
1544        64.33333333
1584        66
1591        66.29166667
1632        68
1680        70
1728        72
1765        73.54166667
1776        74
1811        75.45833333
1824        75.95833333
1853        77.16666667
1872        77.95833333
1896        78.95833333
1920        79.95833333
1939        80.75
1968        81.95833333

Як ви бачите, він розміщує iframe кожні 2 секунди AND на scenecut (секунди з плаваючою частиною), що на мою думку важливо для складності відеопотоку.

Розміри генерованих файлів майже однакові. Дуже дивно, що навіть при більшій кількості ключових кадрів у методі 3 він створює інколи менше файлу, ніж стандартний алгоритм бібліотеки x264.

Для генерації декількох бітрейт-файлів для потоку HLS ми вибираємо метод три. Він ідеально співпадає з 2 секундами між шматками, у них є рамка кадрів на початку кожного фрагменту, і вони мають додаткові рамки кадрів на складних сценах, що забезпечує кращий досвід користувачам, які мають застарілі пристрої та не можуть відтворювати високі профілі x264.

Сподіваюся, це комусь допоможе.


Фантастично, дякую за ваші 50 копійок!
BrunoFenzl

7

Тому, здається, відповідь така:

  • Метод 1 перевірений, що працює, але є libx264специфічним і коштує усунення дуже корисного scenecutваріанту в libx264.
  • Спосіб 3 працює з версії FFMPEG з квітня 2015 року, але слід перевірити свої результати за допомогою скрипту, який міститься внизу цієї публікації, оскільки документація FFMPEG незрозуміла щодо ефекту цього варіанту. Якщо він працює, він перевершує два варіанти.
  • НЕ ВИКОРИСТОВУЙТЕ метод 2, -gвидається застарілим. Він ні, як видається, не працює, а також не визначено в документації, не знайдений у довідці, як і не використовується в коді. Перевірка коду показує, що ця -gопція, ймовірно, призначена для потоків MPEG-2 (навіть існують кодові строфи, що стосуються PAL та NTSC!).

Також:

  • Файли, згенеровані методом 3, можуть бути трохи більшими, ніж метод 1, оскільки дозволені кадри між проміжками I (ключові кадри).
  • Ви повинні явно встановити прапор "-r" в обох випадках, навіть якщо метод 3 розміщує I кадр у наступному інтервалі кадрів на або після зазначеного часу. Якщо не встановити прапор "-r", ви ставитесь до уваги вихідного файлу, можливо, зі змінною частотою кадрів. Несумісні переходи DASH можуть призвести.
  • Незважаючи на попередження в документації FFMPEG, метод 3 НЕ менш ефективний, ніж інші. Насправді тести показують, що це може бути дещо ефективніше, ніж метод 1.

Сценарій для -force_key_framesваріанту

Ось коротка програма PERL, яку я використовував для перевірки каденції I-кадру на основі виводу пропозиції ffprobe slhck. Схоже, підтверджується, що -force_key_framesметод також буде працювати і має додаткову перевагу від створення scenecutкадрів. Я абсолютно не маю уявлення, як FFMPEG змушує цю роботу, або якщо я просто якось пощастив, тому що мої потоки мають гарний стан.

У моєму випадку я кодував 30 кадрів в секунду з очікуваним розміром GOP 6 секунд або 180 кадрів. Я використовував 180, оскільки аргумент gopsize для цієї програми перевіряв I кадр у кожному кратному 180, але встановлення його на 181 (або будь-яке інше число, не кратне 180), змусило його скаржитися.

#!/usr/bin/perl
use strict;
my $gopsize = shift(@ARGV);
my $file = shift(@ARGV);
print "GOPSIZE = $gopsize\n";
my $linenum = 0;
my $expected = 0;
open my $pipe, "ffprobe -i $file -select_streams v -show_frames -of csv -show_entries frame=pict_type |"
        or die "Blah";
while (<$pipe>) {
  if ($linenum > $expected) {
    # Won't catch all the misses. But even one is good enough to fail.
    print "Missed IFrame at $expected\n";
    $expected = (int($linenum/$gopsize) + 1)*$gopsize;
  }
  if (m/,I\s*$/) {
    if ($linenum < $expected) {
      # Don't care term, just an extra I frame. Snore.
      #print "Free IFrame at $linenum\n";
    } else {
      #print "IFrame HIT at $expected\n";
      $expected += $gopsize;
    }
  }
  $linenum += 1;
}

Лише зауваження: Оскільки це веб-сайт із питань відповідей та не дуже дискусійний форум, де повідомлення впорядковані хронологічно, найкраще ввести всю інформацію в одну відповідь, щоб люди, які шукають рішення, просто повинні прочитати одну публікацію, а не шукати. хто розмістив що, коли :) Я з’єднав ваші відповіді і дав вам +1 і на цьому. Оскільки перехресне повідомлення не дозволено , я б радив видалити своє запитання на веб-сайті Відео. Люди знайдуть відповідь (-и) тут.
slhck

1
У мене просто була ще одна думка (насправді вона піднята у списку розсилки FFmpeg). Коли ви використовуєте force_key_frames, він на зразок псує алгоритм розподілу бітів x264, тому він може дати вам гіршу якість, ніж просто встановлення фіксованого інтервалу ключових кадрів.
slhck

О ні. І ще одна причина, щоб FFMPEG надав кодек-неспецифічний спосіб зробити це, аргумент, який "зробив би найкраще для кодека, про який йдеться". Я спробував подати квиток на це за допомогою trac FFMPEG, але відскочив :-(
Марк Героліматос

@slhck: Чи можете ви детальніше розповісти? Я переглянув архіви списку розсилки в травні 2015 року, але не зміг знайти нічого. Суть полягає у тому, щоб забути про "Спосіб 3" та дотримуватися "Метод 1".
schieferstapel

3
@MarkGerolimatos: приблизно -g, ви говорите: "Здається, це не працює, ... і, здається, не використовується в коді". Я перевірив і вхід gзберігається в avctx->gop_sizeі що libx264 використовує його: x4->params.i_keyint_max = avctx->gop_size;. Коли я перевіряю цей створений тестовий файл:, ffmpeg -i a-test-file.mp4 -g 37 -t 15 gtest.mp4я отримую ключові кадри точно 0,37,74,111,148,185,222,259,296,333,370. GOP може бути скорочений, якщо буде запущена зміна сцени, і для цього -sc_thresholdможна встановити, що також підбирається x264.
Gyan

4

Я хотів додати сюди трохи інформації, оскільки мій гуглінг підняв цю дискусію трохи в своїх пошуках, щоб знайти інформацію про спробу знайти спосіб сегментувати моє кодування DASH так, як я хотів, і жодна інформація, яку я знайшов, була абсолютно коректною.

Спочатку кілька помилок, щоб позбутися:

  1. Не всі I-кадри однакові. Є великі "я" кадри і маленькі "я" кадри. Або використовувати правильну термінологію, I-Frames IDR та I-Frames не-IDR. ІР-кадри IDR (іноді їх називають "ключовими кадрами") створить новий GOP. Кадри без IDR не будуть. Їх зручно мати всередині GOP, де є зміна сцени.

  2. -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE← Це не робить те, що ви думаєте, що робить. Це знадобило мені трохи часу, щоб розібратися. Виявляється, min-keyintкод обмежений. Не дозволяється бути більшим за (keyint / 2) + 1. Таким чином, присвоєння одного і того ж значення цим двом змінним призводить до отримання значення для min-keyintзбиття вдвічі при кодуванні.

Ось у чому річ: сценічна картина дійсно чудова, особливо у відео, яке має швидкі жорсткі розрізи. Це добре і чітко, тому я не хочу його відключати, але в той же час я не міг отримати фіксований розмір GOP до тих пір, поки це було включено. Я хотів увімкнути вирізання сцени, але щоб мати можливість використовувати лише I-кадри без IDR. Але це не працювало. Поки я не зрозумів (з численного читання) про неправильне уявлення №2.

Виявляється, мені потрібно keyintбуло подвоїти бажаний розмір GOP. Це означає, що min-keyintможна встановити бажаний розмір GOP (без внутрішнього коду, розрізавши його навпіл), що запобігає виявленню вирізаного сцени використання IDR I-кадрів усередині розміру GOP, оскільки кількість кадрів з останнього IR-кадру IDR становить завжди менше, ніж min-keyinit.

І, нарешті, налаштування force_key_frameпараметра замінює подвійний розмір keyint. Тож ось що працює:

Я віддаю перевагу сегментам у 2 секунди, тому мій GOPSIZE = Framerate * 2

ffmpeg <other_options> -force_key_frames "expr:eq(mod(n,<GOPSIZE>),0)" -x264opts rc-lookahead=<GOPSIZE>:keyint=<GOPSIZE * 2>:min-keyint=<GOPSIZE> <other_options>

Ви можете підтвердити за допомогою ffprobe:

ffprobe <SRC_FLE> -select_streams v -show_frames -of csv -show_entries frame=coded_picture_number,key_frame,pict_type > frames.csv

У створеному файлі CSV кожен рядок повідомляє вам frame, [is_an_IDR_?], [frame_type], [frame_number]:

frame,1,I,60  <-- frame 60, is I frame, 1 means is an IDR I-frame (aka KeyFrame)
frame,0,I,71  <-- frame 71, is I frame, 0 means not an IDR I_frame

Результат полягає в тому, що ви повинні бачити ID-I-кадри IDR лише з фіксованими GOPSIZEінтервалами, тоді як всі інші I кадри є I-кадрами без IDR, вставленими у міру необхідності для виявлення вирізаного сцени.


це було фантастично! Це було також дуже протизахисно, дякую, що доклали зусиль. І підсумовуючи підсумок, я припускаю, що ваше визначення "I-фреймів" та "i-фреймів" є концептуальним (тобто не можна конфігуруватись експліцитно в libx264), і що "max * 2" було таким, як ви його застосували?
Марк Героліматос

Так, це було концептуально, хоча я бачив, як люди використовують "I" проти "i" для розрізнення I-кадрів IDR від I-IDR. І так, встановлення keyinit на потрібний розмір gop * 2 - це спосіб змусити всі I кадри всередині gop бути не-IDR I-кадрами. Потім ffmpeg -force-key-кадрів перевершує ключ-init у x264opts. В основному це дійсно зворотний спосіб отримати бажаний результат, який був би можливим, якби код x264 дозволив вам встановити min-keyinit та keyinit на одне значення.
Реубен

... в той же час, як увімкнути функцію виявлення вирізаної сцени та отримати фіксований розмір GOP
Реубен

ще раз дякую за вашу приголомшливу роботу! Здається, нам потрібен менш "зворотній" спосіб його виконання
Марк Героліматос

Тут потрібен rc-lookahead? Це впливає на mbtree та VBV, але чи впливає на генерацію i-frame?
Олександр Світкін

0

Схоже, що цей синтаксис не працює завжди. Я перевіряв досить багато вмісту VOD, а також живого контенту (файли звалищ), а іноді scenecut не працює і викликає проміжку між рамками iframe:

Синтаксис для перетворення i50-> p50, 2 секунди перехід / сегмент, IDR на початку, рамки між ними, якщо потрібно

ffmpeg.exe -loglevel verbose -i avc_50i.ts -pix_fmt yuv420p -filter_complex yadif=1,scale=1920:1080 -vcodec libx264 -preset fast -x264-params "rc-lookahead=100:keyint=200:min-keyint=100:hrd=1:vbv_maxrate=12000:vbv_bufsize=12000:no-open-gop=1" -r 50 -crf 22 -force_key_frames "expr:eq(mod(n,100),0)" -codec:a aac -b:a 128k -y target.ts

0

Twitch має пост про це. Вони пояснюють, що вирішили використовувати власну програму з кількох причин; один з них полягав у тому, що ffmpeg не дозволяє запускати різні екземпляри x264 в різних потоках, а натомість присвячує всі вказані потоки одному кадру в одному виході, перш ніж переходити до наступного виводу.

Якщо ви не займаєтесь потоковим потоком у режимі реального часу, у вас більше розкоші. "Правильний" спосіб, ймовірно, кодує в одній роздільній здатності лише розмір GOP, вказаний з -g, а потім кодує інші роздільні рішення, примушуючи кадрами кадрів у тих же місцях.

Якщо ви хотіли це зробити, ви можете використовувати ffprobe для отримання разів ключового кадру, а потім використовувати скрипт оболонки або фактичну мову програмування для перетворення цього в команду ffmpeg.

Але для більшості контенту дуже мала різниця між тим, щоб мати один ключовий кадр кожні 5 секунд та два ключові кадри кожні 5 секунд (один вимушений та один із сценарної кадри). Це приблизно середній розмір I-кадру та розмір P-кадрів та B-кадрів. Якщо ви використовуєте x264 з типовими налаштуваннями (я вважаю, що ви повинні зробити що-небудь, щоб вплинути на це, якщо ви встановите -qmin, як поганий спосіб запобігти x264 використовувати бітрейт на простому вмісті; це обмежує всі типи кадрів на одне значення , Я думаю) і отримаєте такий результат, як I-кадр середнього розміру 46 кБ, P-кадр 24 кБ, В-кадр 17 кБ (наполовину частіший за Р-кадри), то додатковий I-кадр щосекунди на 30 кадрів в секунду є лише на 3% збільшення розміру файлу. Різниця між h264 та h263 може складатися з кути зменшення на 3%, але жодна не є дуже важливою.

Для інших типів вмісту розміри кадру будуть різними. Справедливо кажучи, мова йде про часову складність, а не просторову складність, тому це не просто простий вміст проти жорсткого контенту. Але, як правило, веб-сайти для потокового відео мають обмеження у бітрейті, а вміст із відносно великими I-кадрами - це простий вміст, який буде кодуватися з високою якістю незалежно від того, скільки додаткових кадрів ключів додано. Це марно, але цих відходів зазвичай не помітять. Напевно, найбільш марний випадок - це відео, яке є лише статичним зображенням, що супроводжує пісню, де кожен ключовий кадр точно такий же.

Я не впевнений у тому, як примусові ключові кадри взаємодіють із встановленим обмежувачем швидкості з -maxrate та -bufsize. Я думаю, що навіть у YouTube виникли останні проблеми з правильним налаштуванням налаштувань буфера для забезпечення постійної якості. Якщо ви просто використовуєте середні налаштування бітрейта, як це можна побачити на деяких сайтах (оскільки ви можете перевірити параметри x264 в атомі заголовка / mov? За допомогою шестигранного редактора), то модель буфера не є проблемою, але якщо ви Обслуговуючи створений користувачем вміст, середній бітрейт спонукає користувачів додавати чорний екран у кінці відео.

Варіант -g Ffmpeg або будь-який інший варіант кодера, який ви використовуєте, відображається на специфічний для кодера варіант. Отже, '-x264-params keyint = GOPSIZE' еквівалентно '-g GOPSIZE'.

Одна з проблем виявлення сцени полягає в тому, якщо ви з будь-якої причини віддаєте перевагу ключовим кадрам поблизу певних номерів. Якщо кожні 5 секунд ви вказуєте ключові кадри та використовуєте виявлення сцени, а зміна сцени відбувається на 4,5, то її слід виявити, але тоді наступний ключовий кадр буде о 9.5. Якщо час продовжуватиметься таким чином, ви можете закінчити ключові кадри у 42,5, 47,5, 52,5 тощо, замість 40, 45, 50, 55. І навпаки, якщо зміна сцени в 5,5, то буде ключовий кадр у 5 та 5,5 буде занадто рано для іншого. Ffmpeg не дозволяє вам вказати "зробити тут ключовий кадр, якщо в наступні 30 кадрів не буде зміни сцени". Хтось, хто розуміє C, міг би додати цей варіант.

Для відео зі змінною частотою кадрів, коли ви не використовуєте потокову трансляцію, як Twitch, ви повинні мати змогу використовувати зміни сцени без постійного перетворення на постійну частоту кадрів. Якщо ви використовуєте фільтр 'select' у ffmpeg і використовуєте константу 'scene' у виразі, тоді вихід налагодження (-v налагодження або натискання '+' кілька разів під час кодування) показує номер зміни сцени. Це, мабуть, відрізняється від і не настільки корисного, як число, яке використовує x264, але воно все-таки може бути корисним.

Тоді процедура, ймовірно, повинна зробити тестове відео, яке призначене лише для зміни ключових кадрів, але, можливо, воно може використовуватися для даних контролю швидкості, якщо використовується 2-прохідний. (Не впевнений, що згенеровані дані взагалі корисні для різних дозволів та налаштувань; даних макроблок-дерева не буде.) Перетворіть його у відео з постійним кадром, але дивіться цю помилку щодо заїкання виходу, коли вдвічі зменшується частота кадрів, якщо ви коли-небудь вирішите використовувати фільтр fps для інших цілей. Запустіть його через x264 з потрібними налаштуваннями ключових кадрів та GOP.

Тоді просто використовуйте ці ключові рамки разом з оригінальним відеозмінною частотою кадрів.

Якщо ви дозволяєте повністю божевільний вміст, створений користувачем, з 20-секундним розривом між кадрами, то для кодування змінної частоти кадрів ви можете розділити вихід, використовувати фільтр fps, якось використовувати фільтр вибору (можливо, побудувати дійсно довге вираження, яке має щоразу), або, можливо, ви можете використовувати тестовий відеоролик як вхідний сигнал, або розшифрувати лише ключові кадри, якщо ця опція ffmpeg працює, або використати фільтр вибору для вибору ключових кадрів. Потім масштабуйте його до потрібного розміру (для цього є навіть фільтр scale2ref) і накладіть на нього оригінальне відео. Потім використовуйте перемежований фільтр, щоб поєднати ці призначені для примусового використання ключові кадри з оригінальним відео. Якщо це призведе до двох кадрів, розміром яких є 0,001 сек один від одного, що перемежуючий фільтр не заважає, то вирішіть цю проблему самостійно за допомогою іншого фільтра вибору. Тут може бути головна проблема взаємодії з обмеженнями буфера кадру для фільтру, що перемежовується. Це все може спрацювати: використовувати якийсь фільтр, щоб захистити щільніший потік (фільтр-фільтр?); посилайтеся на вхідний файл кілька разів, щоб він декодувався не один раз, і кадри не потрібно зберігати; використовувати фільтр «streamselect», який я ніколи не робив, саме в ті часи ключових кадрів; покращити фільтр перемежування, змінивши його поведінку за замовчуванням або додавши опцію для виведення найстарішого кадру в буфер, а не скидання кадру. чого я ніколи не робив, точно в ті часи ключових кадрів; покращити фільтр перемежування, змінивши його поведінку за замовчуванням або додавши опцію для виведення найстарішого кадру в буфер, а не скидання кадру. чого я ніколи не робив, точно в ті часи ключових кадрів; покращити фільтр перемежування, змінивши його поведінку за замовчуванням або додавши опцію для виведення найстарішого кадру в буфер, а не скидання кадру.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.