Сведение слоёв распаковывает исходник видеокартой

Затухание в полторы-две минуты собиралось минутами, и всё это время
предпросмотр ждёт. Виноваты оказались не фильтры: на десяти секундах
2688x1512 цепочка со сведением стоит 13.5 с, а вовсе без фильтров —
12.7 с. Время уходит на разбор HEVC процессором.

Ключ -hwaccel cuda перед входом убирает почти всё: настоящее затухание
на семьдесят секунд собирается 18.3 с вместо 75.9 с, картинка бит в бит
та же (одинаковый md5 потока, 4196 кадров там и там).

Просится он только там, где кодировать будет та же карта — то есть
выбран NVENC. На машине без неё ключ не появляется вовсе. Сверх того у
подготовки вставок есть откат: не пошло — повторяем на процессоре, как
это уже делает склейка с перекодированием.

Сборка ролика пока по-старому: там кусок с наложением идёт в общий
поток, и повторить его после отказа посреди работы нельзя — данные уже
ушли в трубу. Это отдельная задача.
This commit is contained in:
4aiman 2026-10-01 15:11:43 +03:00
commit 8d1cb9af5c
4 changed files with 109 additions and 5 deletions

View file

@ -15,6 +15,7 @@ uses
{ Interfaces нужен, чтобы связалась вся LCL и заработала загрузка
файлов форм. }
Interfaces, Forms, Controls, Classes, SysUtils, Math, TypInfo, uTheme,
uFfmpegCmd, uAppTypes,
uMediaProbe, uProject, uTransform, uTimelineCtrl,
uPanCropForm, uDepsForm, uMismatchForm, uProgressForm, uProjectInfoForm,
uRemuxForm;
@ -844,6 +845,59 @@ begin
TransformFitsOutputCrop(T));
end;
{ Сведение слоёв просит распаковку у видеокарты.
На длинном затухании это разница между тремя минутами и одной, а
ключ входной: ffmpeg принимает его только перед тем входом, к которому
он относится. Забыть его легко и незаметно — команда останется рабочей,
просто медленной. }
procedure CheckLayerHwDecode;
var
Layers: array[0..0] of TSegmentLayer;
A: TArgs;
I, Hw, Input: Integer;
begin
WriteLn;
WriteLn('Распаковка слоёв видеокартой');
WriteLn;
Layers[0] := Default(TSegmentLayer);
Layers[0].FilePath := '/несуществующий/видео.mp4';
Layers[0].SrcStart := 10;
Layers[0].FadeFrom := 1;
Layers[0].FadeTo := 0;
A := ArgsRenderLayers(Layers, '/выход.mkv', 70, 2688, 1512, 60000, 1001,
'yuv420p', 'hevc', False, 0, '', NotPiped, False);
Hw := -1;
for I := 0 to High(A) do
if A[I] = '-hwaccel' then
Hw := I;
CheckTrue('без просьбы ключа нет', Hw < 0);
A := ArgsRenderLayers(Layers, '/выход.mkv', 70, 2688, 1512, 60000, 1001,
'yuv420p', 'hevc', False, 0, '', NotPiped, True);
Hw := -1;
Input := -1;
for I := 0 to High(A) do
begin
if A[I] = '-hwaccel' then
Hw := I;
if (A[I] = '-i') and (Input < 0) then
Input := I;
end;
{ Просьба выполняется только там, где кодировать будет та же карта. На
машине без неё проверять нечего, и это не поломка. }
if Pos('nvenc', PreferredEncoder('hevc')) = 0 then
WriteLn(' -- видеокарты для кодирования нет, проверять нечего')
else
begin
CheckTrue('по просьбе ключ появляется', Hw >= 0);
CheckTrue('и стоит перед входом, а не после', (Hw >= 0) and (Hw < Input));
end;
end;
procedure CheckButtonClicks;
var
Btn: TButtonProbe;
@ -904,6 +958,7 @@ begin
CheckSplitAllTracks;
CheckGapTolerance;
CheckSourceRect;
CheckLayerHwDecode;
CheckButtonClicks;
WriteLn;