Жахіття з кольорами: перекодування Ffmpeg і збереження BT.601

Час від часу ви доволі несподівано можете опинятися у чудернацьких хащах редагування цифрового відео Наприклад, вам просто потрібно порізати якісь записи з екрана, які зроблено на мобільному пристрої, зокрема планшеті або мобільному телефоні, лише щоб отримати матеріал, у якому щось не так з кольорами.

«Звичайний» матеріал

Драма розпочинається з матеріалу запису з екрана, який є доволі невинним і звичайним з першого погляду. Його могло бути записано на пристроях Android 7 за допомогою програми для запису з екрана (зокрема «AZ Screen Recording», але не підробкою з суфіксом «Pro»). І цей матеріал має дві трохи незвичні властивості:

  • значна зміна частоти кадрів,

  • використано BT.601[1], замість BT.709[2], як у більшості сучасних матеріалів високої роздільності.

Ніяких проблем не має бути, чи не так? Гаразд…

Виявляється, мультимедійний рушій Kdenlive, MLT має певні проблеми із відеоматеріалом зі значним розбігом частот кадрів, зокрема розбігом від 0,001 до понад 100 кадрів за секунду Симптоми незначні, але можуть зашкодити якості результатів: здається, MLT може вибирати наступний кадр доволі неправильно у ділянках із низькою частотою кадрів. Це не так помітно для досить високих частот кадрів, але може давати неоковирні результати в інших місцях. Наприклад, реакція на дотик користувача з’являлася за декілька секунд до самого торкання. Ймовірно, це спричинено дуже низькою частотою кадрів під час періоду неактивності одразу перед взаємодією з користувачем.

Перекодування до фіксованої частоти кадрів справді є одним з простих завдань ffmpeg (у цьому прикладі ми припускаємо сталу частоту кадрів проєкту у 25 кадрів за секунду):

ffmpeg -i raw.mp4 -r 25 -crf 18 screen-rec.mp4

Стала частота кадрів усування згадані вище проблеми, отже результат буде очікуваним. Але…

Просте перекодування: розфарбуй мене усю

transcoding_color_change.webp

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

Якщо поглянути прискіпливіше або за допомогою вбудованої панелі властивостей кліпу Kdenlive, або за допомогою ffprobe, бачимо, що перекодований файл не містить зазначення профілю кольорів BT.601. Втім, ffmpeg не перетворював кольорів під час перекодування, — правильні дані щодо профілю кольорів було просто відкинуто!

Паліативні заходи

kdenlive2308_clip_properties_color_space.webp

Перевизначення простору кольорів у властивостях кліпу

Звичайно ж, у Kdenlive завжди є можливість перезаписати властивості початкового кліпу за допомогою вбудованому віджеті властивостей кліпу.

Просто виберіть кліп із перекодованим відео на панелі контейнера проєкту Потім перейдіть на панель властивостей кліпу і перейдіть на вкладку «Примусові властивості» document-edit. Позначте пункт Простір кольорів, а потім виберіть ITU-R 601. Тепер Kdenlive застосує належний профіль кольорів.

Хоча цей спосіб дуже простий, він має власні обмеження; він працює добре, доки ви продовжуєте працювати лише у редакторі Kdenlive і його обробнику MLT. Але щойно вам потрібно скористатися зовнішніми засобами для роботи з відео, зокрема ffmpeg для видобування зображення, усе пропало: ці засоби нічого не знають про перевизначення властивостей початкового кліпу у Kdenlive. Тому нам потрібно записати належні дані щодо профілю кольорів у самі перекодовані файли відео.

Збереження BT.601 при перекодуванні

Що гірше, очевидне перетворення профілю кольорів за допомогою

-vf colormatrix=bt601:bt601

просто не працює: ffmpeg скаржиться про те, що неможливо перетворення між однаковими вхідним і вихідним профілем кольорів.

Шматочок мозаїки, якого не вистачає, можна знайти на сайті Stack Exchange сайта питань і відповідей щодо роботи з відео у дописі 2015 року «ffmpeg: explicitly tag h.264 as bt.601, rather than leaving unspecified?».

Є ще одна річ, яку слід врахувати: BT.601 має варіанти PAL і NTSC, які мають дещо різні основні колірності, криві перетворення і простори кольорів. Тому початковий матеріал слід спочатку визначити за допомогою ffprobe (або MediaInfo), яку було використано під час записування у вашому випадку. Будь ласка, зауважте, що взагалі немає значення, чи має ваш запис з екрана роздільну здатність зі стандартного набору, але ця роздільна здатність має значення при кодуванні кольорів.

PAL та NTSC DNA

Отже, як нам визначити, що у певному файлі запису відео, скажімо raw.mp4, використано простір кольорів PAL чи NTSC? Звичайно ж, нам на допомогу прийде ffprobe. Але щоб не загубитися серед усіх цих подробиць, які ffprobe видасть нам, вам слід вгамувати його параметрами та grep:

ffprobe -v error -show_streams raw.mp4 | grep color_

Це дасть вам щось схоже на це:

color_range=tv
color_space=bt470bg
color_transfer=smpte170m
color_primaries=bt470bg

Рядок color_space=... повідомляє нам, з чим ми маємо справу, з PAL (bt470bg) або з NTSC (smpte170m).

PAL

Якщо це колірності PAL (color_space=bt470bg), нам доведеться далі перекодувати дані так:

ffmpeg -i raw.mp4
-color_primaries bt470bg -color_trc gamma28 -colorspace bt470bg
-r 25 -crf 18 screen-rec.mp4

NTSC

Для колірностей NTSC (color_space=smpte170m) нам знадобиться інший набір основ, крива перетворення та простір кольорів:

ffmpeg -i raw.mp4
-color_primaries smpte170m -color_trc smpte170m -colorspace smpte170m
-r 25 -crf 18 screen-rec.mp4
transcoding_comparison.webp

За будь-яких умов, Kdenlive/MLT бачитиме перекодоване відео належним чином, з використанням профілю кольорів BT.601. Крім того, інші інструменти обробки мультимедійних даних також належними чином визначатимуть профіль кольорів — якщо у них немає загальних проблем із обробкою BT.601.

Нотатки

Джерела

Початковий текст було подано користувачем TheDiveO до зниклого тепер блогу kdenlive.org. Для цієї документації його було запозичено з kdenlive.org і адаптовано до загального стилю.