Färghelvete: Omkoda och bevara BT.601 med ffmpeg¶
Då och då kan man helt oväntat komma in på konstigt digitalt videoterritorium . Som exempel, man vill helt enkelt redigera några skärminspelningar gjorda på en mobilenhet, såsom en surfplatta eller mobiltelefon, bara för att råka ut för att något är fel med färgerna.
Ordinärt filmmaterial¶
Dramat börjar med skärminspelningar som verkar helt oskyldiga och normala vid första anblicken. De kan ha spelats in på Android 7-enheter med en applikation för skärminspelning (som «AZ Screen Recording», men inte förfalskningen ”Pro”). Men filmmaterialet har två lite ovanliga egenskaper:
en mycket variabel bildhastighet,
det använder BT.601[1], istället för BT.709[2] som så mycket HD-filmmaterial nu för tiden.
Ska inte orsaka några problem, eller hur? Nja …
Det visar sig att Kdenlives mediegränssnitt MLT kan uppvisa vissa problem med videomaterial som har mycket variabel bildhastighet, till exempel mellan 0,001 och 100+ b/s. Symptomen är subtila, men äventyrar produktionskvaliteten: det verkar som om MLT mycket väl kan välja en framtida bildruta som är långt bort i områden med låg bildhastighet. Även om det inte är ett problem för en lämpligt hög bildhastighet, orsakar det udda resultat på andra ställen. Till exempel visas när användaren rör vid skärmen upp till flera sekunder innan själva interaktionen dyker upp. Det beror förmodligen på en mycket låg bildhastighet under perioden utan aktivitet precis innan användarinteraktionen.
Omkodning till en fast bildhastighet är säkerligen en av de enklaste uppgifterna i ffmpeg (exemplet antar en konstant bildhastighet i projektet på 25 b/s):
ffmpeg -i raw.mp4 -r 25 -crf 18 screen-rec.mp4
Den konstanta bildhastigheten löser problemen som nämns ovan, så resultaten är som förväntat. Bortsett från …
Enkel omkodning: inte alls¶

Tyvärr visar den resulterande videon nu annorlunda färger! Det kanske inte är så uppenbart i början, men det kan vara rätt framträdande när man arbetar mer med filmmaterialet. Och åskådarna ser det tydligt om man blandar materialet sida vid sida med ytterligare bearbetade versioner av det, såsom extraherade bildrutor för stillbilder.
En närmare inspektion antingen med hjälp av Kdenlives inbyggda fönster för klippegenskaper eller ffprobe avslöjar att den omkodade filen saknar BT.601 färgprofilindikering. Ändå, förvandlade inte ffmpeg färgerna alls under omkodningen utan tappade helt enkelt bort rätt färgprofilinformation!
Provisoriska åtgärder¶

Överskrida klippegenskapernas färgrymd¶
Naturligtvis finns alltid Kdenlives förmåga att skriva över källklippets egenskaper med hjälp av den inbyggda komponenten för klippegenskaper.
Markera helt enkelt det omkodade videoklippet i projektkorgen. Gå sedan till klippegenskaper och välj fliken ”Tvinga egenskaper” . Markera Färgrymd och välj sedan ITU-R 601. Kdenlive inför nu rätt färgprofil.
Även om den är väldigt enkel, har metoden sina begränsningar: Den är bra när man enbart fortsätter att arbeta i Kdenlive-editorn och dess MLT-återgivning. Men så fort man behöver koppla in externa videoverktyg, som ffmpeg för bildextrahering är man förlorad, eftersom verktygen inte känner till ändringarna av källklippets egenskap i Kdenlive. Vi behöver alltså få in rätt färgprofilinformation direkt i de omkodade videofilerna själva.
Bevara BT.601 vid omkodning¶
För att göra saken värre, den till synes uppenbara transformeringen av färgprofilen
-vf colormatrix=bt601:bt601
fungerar helt enkelt inte: ffmpeg klagar på att det inte går att omvandla mellan samma färgprofil för indata och utdata.
Den saknade pusselbiten finns på Stack Exchange-webbplatsen med frågor och svar om videoproduktion i ett inlägg från 2015 med frågan ”ffmpeg: explicitly tag h.264 as bt.601, rather than leaving unspecified?”.
Det finns en hake att hålla utkik efter: BT.601 finns i varianter för PAL och NTSC som har något olika grundfärger, överföringskurvor och färgrymder. Så undersök först råmaterialet med ffprobe (eller MediaInfo) vilken har använts under inspelningen i detta fall. Observera att det inte alls spelar någon roll att skärminspelningen inte har standardupplösning (SD), men det spelar roll när det gäller färgkodning.
PAL och NTSC DNA¶
Så hur tar vi reda på om en given videoinspelning, säg raw.mp4
, använder PAL- eller NTSC-färgrymd? Naturligtvis räddar oss ffprobe. Men för att inte gå vilse bland alla ovidkommande detaljer ffprobe häver ur sig, måste vi tämja det med några väljare och grep:
ffprobe -v error -show_streams raw.mp4 | grep color_
Det borde ge dig något i den här stilen:
color_range=tv
color_space=bt470bg
color_transfer=smpte170m
color_primaries=bt470bg
Raden color_space=...
berättar om vi har att göra med PAL (bt470bg) eller NTSC (smpte170m).
PAL¶
Om det är PAL-kromatitet (color_space=bt470bg
), måste vi omkoda på följande sätt:
ffmpeg -i raw.mp4
-color_primaries bt470bg -color_trc gamma28 -colorspace bt470bg
-r 25 -crf 18 screen-rec.mp4
NTSC¶
För NTSC-kromatitet (color_space=smpte170m
), behöver vi en annan uppsättning grundfärger, överföringskurva och färgrymd.
ffmpeg -i raw.mp4
-color_primaries smpte170m -color_trc smpte170m -colorspace smpte170m
-r 25 -crf 18 screen-rec.mp4

I alla fall ser Kdenlive och MLT nu den omkodade videon korrekt med hjälp av färgprofilen BT.601. Dessutom detekterar andra medieverktyg också färgprofilen, om de inte är så felaktiga att de inte alls förstår BT.601.
Anmärkningar
- Källor
Den ursprungliga texten skickades in av användaren TheDiveO till den nu nedlagda bloggen kdenlive.org. För den här dokumentation har den hämtats från kdenlive.org och anpassats för att motsvara den övergripande stilen.