VP9 do HEVC bez komprese pomocí FFMpeg

Jigdo

  • *****
  • 501
    • Zobrazit profil
VP9 do HEVC bez komprese pomocí FFMpeg
« kdy: 27. 09. 2024, 20:27:18 »
EUMETSAT maji peknou animaci pocasi ve 4K,
kterou zverejnili na YT.
https://www.youtube.com/watch?v=DAW-GpnJIgE

Uvedene video jsem si stahl ve kodeku 625 a 140
Kód: [Vybrat]
yt-dlp -f 625+140 DAW-GpnJIgE(625 ma nejvyssi video bitrate)

Kód: [Vybrat]
140     m4a   audio only      2 │    4.71MiB   129k https │ audio only           mp4a.40.2  129k 44k medium, m4a_dash
625     mp4   3840x1920   30    │ ~556.09MiB 15294k m3u8  │ vp09.00.50.08 15294k video only

a chtel bych to video dostat z VP9 do HEVC,
jelikos ten VP9 kodek nefunguje na starsich zarizenich,
ale pri konverzi na HEVC je ta ztrata kvality videt .. na 4K monitoru
z 493.5M je vysledne video v HEVC 92.1M :(
(Original VP9 video ma
Bit rate : 13.4 Mb/s
a vysledne HEVC video
Bit rate : 2 371 kb/s)
 
Napada nekoho jak to z toho VP9 dostat do HEVC
aniz by FFMpeg snizil bitrate toho videa?


Kód: [Vybrat]
ffmpeg -hide_banner \
-y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda \
-i Global.weather.2024-April-June.f625+140.[DAW-GpnJIgE].mp4 \
-strict experimental \
-map 0:0 -map 0:1 -map 0:2 \
-c:V:0 hevc_nvenc \
-c:v:1 copy \
-c:a copy \
-c:s copy \
-c:d copy \
-map_metadata 0 \
-f mp4 -movflags +faststart \
-ignore_unknown -copy_unknown \
Global.weather.2024-April-June.HEVC+140.[DAW-GpnJIgE].mp4 -v verbose
« Poslední změna: 27. 09. 2024, 20:33:35 od Jigdo »


Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #1 kdy: 27. 09. 2024, 23:05:55 »
bez hw akcelerace... to jsou uplně jiný světy co se týče kvality a rychlosti. (a číselně -vcrf u sw odpovídá  global_quality:v jinak), a hlavně používám lookahead 1 (mapuje se na LA_ICQ) . a něco jako preset jde ladit přes "TU" ("target usage" 1-7)

cuda neznám, možná má svoji sadu parametrů
ale tohle api možná doznalo změn, zprovoznění quicksync před x lety chtělo hodně laborování a explicitně uvádět spoustu boilerplate přepínačů

Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #2 kdy: 28. 09. 2024, 09:53:38 »
V tom použitém příkazu tam nikde nemáte deklarovaný bitrate, ani kvalitu u výstupního video streamu.
Navzdory nadpisu threadu to nebude HEVC bez komprese (to byste měl obří bitrate)
Také jsou tam nějaké úplně zbytečné parametry - mapování, ignore_unknown a copy_unknown se vylučují atp., experimental nepotřebujete, ale to nezpůsobuje ten problém, co řešíte.

ffmpeg má možnost určité kodeky kódovat více enkodéry. Tzn. když máte NVIDIA kartu, tak se pro HEVC (H.265) nabízí buď hevc_nvenc, nebo softwarový libx265, který funguje všude. (jsou ještě jiné alternativy jako kvazaar, svt-hevc, ale to je specifické pro konkrétní kompilaci).

Různé enkodéry jsou různě namapované na parametry řízení výst. bitrate / kvality v ffmpegu. Tzn. můžete sice použít některé parametry (např. -q:v <číslo>, -maxrate, -minrate), ale pokud tenhle konkrétní parametr není namapován, nebo enkodér není ve správném režimu, tak to nemá vůbec žádný efekt i když je uvedete.
Pak jsou tam ještě specifické parametry pro daný enkodér. Doporučuji si prohlédnout (neznamená, že je vždy dobré je nastavovat) pomocí vestavěného helpu, protože máte jistotu, že je to k té konkrétní verzi enkodéru/knihovny, co můžete použít. Např. ffmpeg -h encoder=libx265 nebo ffmpeg -h encoder=hevc_nvenc

Obecně platí, že x265 enkodér postkytuje kvalitnější výstup vzhledem k bitrate než hardwarové enkodéry (NVENC, Intel QSV, AMD AMF), ale samozřejmě výstup se kóduje déle, pokud nemáte nějaký mega stroj.
Ale ve většině případů jsou výstupy samozřejmě použitelné i s těmi hw enkodéry, jen musíte trochu přitlačit na bitrate.

U lib_x265 bych doporučil (beru standardní používání, nikoliv nějaké patologické obrazce nebo super komplikované scény, kdy se potřebujete za každou cenu trefit do co nejmenšího souboru i za cenu násobně delšího kódování třeba víceprůchodem) zůstat u CRF řízení ( vysvětlení https://slhck.info/video/2017/02/24/crf-guide.html ).
Tzn. pro váš případ, když to zjednoduším.

ffmpeg -i vstup.mp4 -c:a copy -c:v libx265 -crf 25 vystup.mp4

Čím vyšší číslo CRF, tím menší datový tok. Není to lineární a v podstatě platí, že pro menší rozlišení např. SD PAL, potřebujete vyšší CRF např. 18, a pro vyšší rozlišení pak stačí naopak nižší CRF, např. 25-28 pro UltraHD. Dolaďte podle potřeby.

U NVENC je to trochu složitější, protože CRF, q:v ignoruje. A v podstatě jsou při jednoprůchodu použitelné dva parametry: CBR, kdy se snaží udržet okolo zadaného bitrate. QP (quantization parameter), kdy se enkodér snaží udržet relativní degradaci obrazu a může fluktuovat bitrate - což je trochu podobné zmíněnému CRF a také platí, že vyšší číslo znamená vyšší degradaci a menší bitrate.

pro CBR s NVENC stačí nastavit bitrate pro stream a většinou je to naprosto dostačující
ffmpeg  -hwaccel cuda -hwaccel_output_format cuda -i vstup.mp4 -c:a copy -c:v hevc_nvenc -b:v 15M vystup.mp4

pro QP je pak potřeba přepnout režim rate control (přes parametr rc)
ffmpeg  -hwaccel cuda -hwaccel_output_format cuda -i vstup.mp4 -c:a copy -c:v hevc_nvenc -rc constqp -qp 28 \
vystup.mp4

Jak tu bylo zmíněno, tak jsou tam i další paramtery, třeba pro ten rc-lookahead (načítá snímky dopředu, aby lépe rozdistribuoval bitrate) a implicitně to pak zapíná dynamické vkládání intra a b-snímků. Což může být zajímavé pro rychle se měnící videa (což není ten případ satelitních snímků) s menším bitrate.
Případně je tam i možnost použít další specifické kvantizační mechanismy nad rámec standardního rc. spatial (v rámci snímku) a temporal (mezi snímky) přes parametry spatial_aq, resp. temporal_eq. Ale zpomalí to kódování a musíte si vyzkoušet, jestli to něco udělá.

_Jenda

  • *****
  • 1 600
    • Zobrazit profil
    • https://jenda.hrach.eu/
    • E-mail
Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #3 kdy: 29. 09. 2024, 01:11:47 »
Tzn. pro váš případ, když to zjednoduším.

ffmpeg -i vstup.mp4 -c:a copy -c:v libx265 -crf 25 vystup.mp4
Přesně tak. Ještě bych zvážil, pokud tolik nezáleží na času a CPU komprese:
  • -preset slow - pomalejší běh ale menší výsledný soubor. Jedna z věcí kterou ovlivňuje je třeba ten tebou zmíněný rc-lookahead - viz https://x265.readthedocs.io/en/stable/presets.html
  • -x265-params pools=none (nebo třeba 4) - vypnutí multithreadingu, x265 nějak paralelizuje přes snímky a má pak prý horší kompresi, protože nemůže využít všech rozdílů mezi snímky

Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #4 kdy: 29. 09. 2024, 10:03:46 »
Nekóduju hodinová videa (a pořád používám kodek AVC  x264 / h264_qsv )  Já to ale beru tak, že (u mě quicksync) je brutálně rychlý, takže -look_ahead to sice znatelně zpomalí (možná o 30%).

- k té nelinearitě crf: ona ani není zaměnitelná mezi kodeky (v mém případě x264 a h264_qsv): x264 to ta volba dává plné spektrum možností (22= top kvalita, nad 35 už je to DivX z roku 2006), tak u qsv prakticky jakékoli číslo dává slušně vypadající video, ale i hodně vysoká čísla dávají pořád o dost vyšší bitrate, takže volím vyšší čísla (35 pro qsv, a 28 pro crf x264), protože sw kodek "dokáže" video zmenšit až na kost,
-konstatní kvantitizér se už dávno nedoporučuje
-na nějaké ladění kodeků jsem se vykašlal, používám jenom ten preset (ty slow(er.est), fas(er,est),normal medium)

Následující platí pro verzi, kterou mám já, je možné, že v aktuální, už je to user friendly  (v rámci CLI  ;D ) a správně se mapují
-presety fungují jen pro softwarový kodeky, pro QS je ten parametr "TU" (nevím jaký je název parametru do příkazové řádky, možná to taky bude -preset)
-crf u quicksync nefunguje (zapisuje se jinak, asi přes -q:v)


Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #5 kdy: 30. 09. 2024, 00:29:28 »
Přesně tak. Ještě bych zvážil, pokud tolik nezáleží na času a CPU komprese:

Ano, výběr výpočetně náročnějšího presetu je samozřejmě další možnost. Ale většinou to opravdu začne dávat smysl v momentě, kdy jsem omezený velikostí/bitratem a mám třeba trochu komplikovanější scény (šum, déšť, kresba v tmavých plochách nebo hodně pohybu).
Ještě dodám, spíš pro info a tazatele, kdyby si s tím chtěl hrát (přestože zrovna u tohohle relativně jednoduchého videa z MSG, mi přijde, že by se to začalo výrazněji projevovat až tak na polovičním bitrate okolo 6-8 Mbit/s, pro pokusy bych dal spíš typově něco jako sport nebo jízdu na horské dráze :))

Pokud se u x265 jen přepne na vyšší preset (z medium na slow, případně slower), tak se bez úpravy CRF výsledný soubor typicky zvětší. Krom zmíněného delšího lookaheadu, to ovlivní např. i pohybovou analýzu - zapne to pokročilejší partitioning v prediktoru, star ME, zvýší se počet iterací v subpel ME atp.
Jinak řečeno, je tam víc detailů k zakódování.
Takže je třeba kompenzovat vyšším CRF nebo QP pro případné snížení velikosti, pokud o to jde.

Citace
  • -x265-params pools=none (nebo třeba 4) - vypnutí multithreadingu, x265 nějak paralelizuje přes snímky a má pak prý horší kompresi, protože nemůže využít všech rozdílů mezi snímky

Tohle bych úplně nedělal. Sám jsem šoupal s poolem akorát v případě, kdy jsem řešil souběžný běh na dvou-socketovém transkódovacím serveru, s více souběžnými úlohami.

Ale k meritu věci. Ano teoreticky při nějakých hodně dynamických scénách a specifickém nastavení to může zhoršit predikci pohybu, i alokaci (RC). Ale mimo nějaké patologie to bude ve výsledku se budeme bavit max. o nějakých hodnotách třeba do procenta velikosti se stejnou degradací.
Pokud bych měl tvrdý velikostní limit, čas si s tím hrát a něco by se mi třeba začalo obrazově sypat, bylo by to až někde na konci těch možných optimalizací. Je tam x dalších a podle mě zásadnějších parametrů, které můžou ovlivnit kompresi (např. ten výčet, co ovládá, parametr film-grain, různé parametrizace přes vážení).
A když už bych chtěl tohle vypnout, tak spíš sáhnu po parametru --frame-threads a ten nastavím na 1 (nebo kolik chci).
Pokud nastavím pools=none, tak nejen že to komplet vše serializuju (včetně věcí, co nemají vliv na výstup) a bude to líné jak vandrácká hůl, protože komplet vypnu asynchronní workery, ale implicitně vyruším i paralelizaci při zpracování CTU (32x36 nebo 64x64 px ekvivalent makrobloku z MPEGu) v rámci snímku.
Tam se používá tzv. WPP, kdy se každý z nich se referencuje na dva okolní (první nad, druhý nad a vpravo). Takže jakmile se udělají první dva CTU, může se spustit další paralelní počítání na řádku pod ním. Což samozřejmě výrazně zrychlí kódování a obráceně i dekódování. Je tam s tím i nějaký drobný overhead ve streamu, protože se musí přidat nějaká metadata a pointery pro skoky na začátky každého řádku, plus se lehce může dál zvětšit stream, kvůli zvýšené entropii z paralelního kódování řádků (vs celého snímku).
Pokud ve streamu tyhle metadata a pointery vůbec nejsou, tzn. když se implicitně vypne WPP, tak pak nemůže paralelizovat ani dekodér a vypneš jednu z výrazných fíčur HEVC. Což já většinou nechci (bude samozřejmě rozdíl, jestli je tam nějaký HW offload, kterému to nevadí dekódovat sekvenčně po jednom CTU a jestli je tam třeba 480p vs 8K. atd.).

Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #6 kdy: 30. 09. 2024, 00:56:34 »
Nekóduju hodinová videa (a pořád používám kodek AVC  x264 / h264_qsv )  Já to ale beru tak, že (u mě quicksync) je brutálně rychlý, takže -look_ahead to sice znatelně zpomalí (možná o 30%).
..
-konstatní kvantitizér se už dávno nedoporučuje
..
-crf u quicksync nefunguje (zapisuje se jinak, asi přes -q:v)

Quicksync (QSV) je něco jiného než NVENC.
Alternativa k CRF (z x264, x265) je to, co jsi už psal, tzn ICQ a LA_ICQ s lookaheadem, parametr je -global_quality.

Bohužel u Intelu je QSV občas problematické, jsou rozdíly nejen mezi hardwary a bohužel i operačními systémy.
https://www.intel.com/content/www/us/en/developer/articles/technical/common-bitrate-control-methods-in-intel-media-sdk.html
ICQ s lookaheadem (LA_ICQ) na Windows funguje jen pro H264, pro HEVC se předá parametr, ale nic to neprovede. Tohle platí minimálně od Skylake až po Comet Lake. Jak je to u novějších XE grafik, nevím.

U NVENCu je v podstatě CBR, VBR (jen přidáš minrate, maxrate k -v:b) a pak zmníněný CQ, který je nejrychlejší. A pokud nevadí, že trochu víc lítá bitrate (pro nějaké archivní účely je to víceméně jedno, pokud to nestreamuješ, nebo nemáš nějaké omezení s konkrétním HW dekodérem). Nad rámec toho se dá zapnout ještě spatial a temporal AQ, což v podstatě dokáže dynamicky přizpůsobit alokaci přidáním na určité statické I snímky, nebo na gradienty v rámci snímku. Ale v podstatě to víceméně spíš přidává nad to, co vyhodnotí ten hlavní vybraný rc mechanismus. Takže ten se za určitých okolností dá i trochu podstřelit.
Ale je to všechno o vyzkoušení na konkrétním materiálu a samozřejmě požadavcích (malý bitrate, nízká latence, nejrychlejší kódování jde typicky proti sobě). A někdy i to, co se obecně nedoporučuje, může pro konkrétní situaci dobře zafungovat.

Jigdo

  • *****
  • 501
    • Zobrazit profil
Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #7 kdy: 30. 09. 2024, 14:53:17 »
Diky vsem za prispevky.

Specificke parametry pro "hevc_nvenc" jsem zkoumal,
ale je jich tam tolik, ze mi vetsina nic nerika :(

Mne jde hlavne o to, ze chci "video" z VP9 do HEVC pokud mozno ve kvalite "1:1"
(to video ma jen 5 min a ve VP9 cca 493.5 M) - aby HEVC nesnizil pri te
konverzi "Bit rate".....a myslel jsem ze FFMpeg pokud neuvedu "-b:v"
provede 1:1 konverzi ..... kvalita nad velikosti...


VP9 original ma 13.4 Mb/s, takze pro jistotu volim 14 Mb/s u "-b:v"
a vysledek vypada na pohled stejne jako ve VP9 :)

Kód: [Vybrat]
ffmpeg -hide_banner \
-y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda \
-i Global.weather.2024-April-June.f625+140.[DAW-GpnJIgE].mp4 \
-map 0:0 -map 0:1 -map 0:2 \
-c:V:0 hevc_nvenc -b:v 14M \
-c:v:1 copy \
-c:a copy \
-c:s copy \
-c:d copy \
-map_metadata 0 \
-f mp4 -movflags +faststart \
-copy_unknown \
Global.weather.2024-April-June.HEVC-B-V-14+140.[DAW-GpnJIgE].mp4 -v verbose



Jeste jsem zkousel "-b:v 0" - range je [0 - 9.22337e+18]
a vysledne video je o velikosti 704.8 M a "Bit rate" 19.2 Mb/s

Kód: [Vybrat]
ffmpeg -hide_banner \
-y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda \
-i Global.weather.2024-April-June.f625+140.[DAW-GpnJIgE].mp4 \
-strict experimental \
-map 0:0 -map 0:1 -map 0:2 \
-c:V:0 hevc_nvenc -b:v 0 \
-c:v:1 copy \
-c:a copy \
-c:s copy \
-c:d copy \
-map_metadata 0 \
-f mp4 -movflags +faststart \
-copy_unknown \
Global.weather.2024-April-June.HEVC-B-V-0+140.[DAW-GpnJIgE].mp4 -v verbose

Re:VP9 do HEVC bez komprese pomocí FFMpeg
« Odpověď #8 kdy: 01. 10. 2024, 13:05:50 »
Jsem rád, že se to povedlo :)

Někdy ve starých verzích ffmpegu (10let+) byl option -sameq, který se snažil nastavit stejný kvanitzér (degradaci) jako u vstupního souboru. Ale s různými kodeky a reprezentacemi toho kvantizéru to nedávalo moc smysl, v nějakých přechodových verzích tam ten option zůstal, a jen se ignoroval, pak ho vyhodili úplně.

Tzn. obecně platí, že pokud žádným způsobem nenastavíte bitrate nebo kvalitu, používá se jen nějaká výchozí hodnota. Nemá to žádnou vazbu na vstupní soubor, pokud tam není třeba nějaká heuristika pro výchozí nastavení v případě externí knihovny (co by mohla např. mít různé výchozí hodnoty podle rozlišení obrazu).

S tím NVENCem je to pak tak, že když se neuvede vůbec žádné nastavení bitrate, tak se použije cílové nastavení 2M jako průměrný bitrate. https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/HEAD:/libavcodec/nvenc_hevc.c#l235

Zajímavý objev s tím, když nastavíte bitrate -b:v 0, to mě nikdy nenapadlo testovat :) V kódu je podmínka, že pokud bitrate nemá hodnotu vyšší než nula, tak se to ignoruje a nenastaví se ni. Tzn. kodér (NVENC knihovna) pak jede v implicitním režimu rc CQ. U mě (Quadro Pascal čip) to pak s -b:v 0 produkuje stejný výsledek jako kdybych použil -cq 1.

Tak veselé kódování :)