From d75596bca3570f76673bbb8d03c3fe9ede659df0 Mon Sep 17 00:00:00 2001 From: 4aiman Date: Thu, 1 Oct 2026 16:24:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=BB=D1=8F=20=D1=80=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D1=91=D1=82=20=D1=80=D0=BE=D0=B2=D0=BD=D0=BE:=20=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=BA=D0=B0=20=C2=ABprogress=3Dcontinue?= =?UTF-8?q?=C2=BB=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D1=83=D0=BB=D1=8F=D0=B5=D1=82=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Показатель висел на пяти процентах, потом прыгал к семидесяти девяти, потом сразу готово. Виноват не ffmpeg: замерено, что он отдаёт ход безупречно ровно — блок каждые полсекунды, 7%, 14%, 20%, 27% и дальше без единого скачка. Блок заканчивается строкой «progress=continue», в которой места нет: она сообщает только, что работа продолжается, и разбор честно оставляет переданное число как было. Я передавал туда ноль, поэтому каждый блок заканчивался обнулением доли. Показатель стоял и дёргался вверх лишь тогда, когда опрос попадал между строкой со временем и этой. Теперь отсчёт начинается с уже известного места — как это давно делает сборка ролика. Проверено глазами на невидимом экране: шесть снимков подряд через полторы секунды дают 54, 65, 74, 82, 91, 99 процентов, полоса растёт вместе с числом. Ловушку закрепляет проверка в tests/lfmcheck: «progress=continue» и «progress=end» узнаются, но времени не трогают. --- README.md | 10 ++++++++++ src/uGenerate.pas | 12 ++++++++++- tests/lfmcheck/lfmcheck.lpr | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ebdb6fd..afc6dfb 100644 --- a/README.md +++ b/README.md @@ -865,6 +865,16 @@ Wine с новой библиотекой не грузилось ничего. привычный RGB. Записанный по привычке код даёт цвет с переставленными красным и синим. +**Последняя строка блока о ходе работы обнуляет место.** ffmpeg шлёт ход +блоками, и заканчивается блок строкой `progress=continue`, в которой +места нет — она сообщает только, что работа продолжается. Разбор честно +оставляет переданное число как было, поэтому передавать туда надо уже +известное место, а не ноль. С нулём доля обнуляется в конце каждого +блока: показатель стоит на месте и дёргается вверх лишь тогда, когда +опрос попадёт между строкой со временем и этой — «висит на пяти +процентах, потом скачет до семидесяти девяти». Сам ffmpeg при этом +отдаёт ход безупречно ровно: блок каждые полсекунды, замерено. + **Разбор HEVC на процессоре — самое дорогое в сведении слоёв.** Не фильтры, как кажется: на десяти секундах 2688x1512 цепочка со сведением стоит 13.5 с, а без всяких фильтров — 12.7 с. Всё время уходит на разбор diff --git a/src/uGenerate.pas b/src/uGenerate.pas index 3bda511..ba91621 100644 --- a/src/uGenerate.pas +++ b/src/uGenerate.pas @@ -168,7 +168,17 @@ var begin if FStepSeconds <= 0 then Exit; - Seconds := 0; + { Отсчёт начинается с уже известного места, а не с нуля. + + ffmpeg шлёт ход работы блоками, и последняя строка блока — + «progress=continue». Места в ней нет, она сообщает только, что работа + продолжается, — и разбор оставляет переданное число как было. Начни + мы с нуля, каждый блок заканчивался бы обнулением доли: показатель + стоял бы на месте и дёргался вверх только в те мгновения, когда + опрос попадал между строкой со временем и этой. Со стороны это + выглядело как «висит на пяти процентах, потом скачет до + семидесяти девяти». } + Seconds := FStepFraction * FStepSeconds; AtEnd := False; if not ParseProgressLine(ALine, Seconds, AtEnd) then Exit; diff --git a/tests/lfmcheck/lfmcheck.lpr b/tests/lfmcheck/lfmcheck.lpr index 2d41043..17d85b2 100644 --- a/tests/lfmcheck/lfmcheck.lpr +++ b/tests/lfmcheck/lfmcheck.lpr @@ -851,6 +851,45 @@ end; ключ входной: ffmpeg принимает его только перед тем входом, к которому он относится. Забыть его легко и незаметно — команда останется рабочей, просто медленной. } +{ Разбор строк о ходе работы ffmpeg. + + Ход приходит блоками, и последняя строка блока — «progress=continue». + Места в ней нет: она сообщает только, что работа продолжается. Разбор + обязан оставить переданное число как было, а вызывающий — передавать + туда уже известное место, а не ноль. Иначе каждый блок заканчивается + обнулением доли, и показатель стоит на месте, дёргаясь вверх лишь + тогда, когда опрос попадёт между строкой со временем и этой. } +procedure CheckProgressParsing; +var + Seconds: Double; + AtEnd: Boolean; +begin + WriteLn; + WriteLn('Разбор хода работы ffmpeg'); + WriteLn; + + Seconds := 0; + AtEnd := False; + CheckTrue('время узнаётся', ParseProgressLine('out_time_us=2500000', + Seconds, AtEnd)); + CheckTrue('и разбирается верно: ' + FloatToStrF(Seconds, ffFixed, 8, 3), + Abs(Seconds - 2.5) < 0.001); + + CheckTrue('«продолжается» — тоже знакомая строка', + ParseProgressLine('progress=continue', Seconds, AtEnd)); + CheckTrue('и она не трогает время: ' + FloatToStrF(Seconds, ffFixed, 8, 3), + Abs(Seconds - 2.5) < 0.001); + CheckTrue('и не объявляет конец', not AtEnd); + + CheckTrue('конец узнаётся', ParseProgressLine('progress=end', + Seconds, AtEnd) and AtEnd); + CheckTrue('время и тут осталось прежним', + Abs(Seconds - 2.5) < 0.001); + + CheckTrue('незнакомая строка не узнаётся', + not ParseProgressLine('bitrate= 12.3kbits/s', Seconds, AtEnd)); +end; + procedure CheckLayerHwDecode; var Layers: array[0..0] of TSegmentLayer; @@ -958,6 +997,7 @@ begin CheckSplitAllTracks; CheckGapTolerance; CheckSourceRect; + CheckProgressParsing; CheckLayerHwDecode; CheckButtonClicks;