Просмотр видео в субпиксельном качестве

Разные проблемы звука, видео, обсуждение разных устройств и т.д.

Модератор: Модераторы разделов

nick87720z
Сообщения: 180
ОС: Gentoo / Calculate

Просмотр видео в субпиксельном качестве

Сообщение nick87720z »

И опять ffmpeg (моя вторая тема про него на форуме).

Пока игрался с ffmpeg - внезапно реализовал сведение графики почти тройного разрешения в субпиксельное по принципу, ранее предложенному с использованием imagemagick: https://legacy.imagemagick.org/discourse-server/viewtopic.php?t=19120

Если строку фильтров ffmpeg засунуть в конфиг плейера типа mpv, то можно смотреть в сверх-качестве прямо в плейере. Хотя тут ещё зависит от железа. На моём Intel B950 (нет ни opencl ни cuda) - при просмотре 4k в разрешении 1600x900 - сам ffmpeg выдаёт от силы 7fps, mpv ещё меньше. Но это без vaapi, т.к. формат файла не поддерживается (с vaapi должно быть чуть больше). Поэтому нормально протестирован только программный вариант, с opencl и cuda могу только надеяться, что заработает :) .

Программный вариант - просмотр в самом ffmpeg:

Shell

# Определяемся с размером на экране, в моём случае - разрешение 1900x600
w=1900
h=600
vidfile=...

ffmpeg -hwaccel auto \
-i "$vidfile" \
-vf "zscale=${w}*3:$h:filter=bilinear, rgbashift=rh=1:bh=-1, scale=$w:$h:flags=area" \
-f opengl "My video"
Некоторые плейеры на базе ffmpeg позволяют установить строку фильтров для ffmpeg.
Пример, для mpv необходимо добавить следующую строку в ~/.config/mpv/mpv.conf:

Код: Выделить всё

vf=zscale=1600*3:900:filter=bilinear,rgbashift=rh=1:bh=-1,scale=1600:900:flags=area
Важно: Если используется аппаратное ускорение, например hwdec=vaapi, то необходимо сменить на вариант *-copy, например vaapi-copy, vdpau-copy и т.д., иначе фильтры не будут работать.
Полный список вариантов для hwdec (работает и для других параметров):

Код: Выделить всё

mpv --hwdec=help
Разбор принципа

Пиксель, как минимальный элемент, имеющий цвет, не может быть уже 3 субпикселов для стандартной модела RGB, однако позиция может быть любой. При этом каждый субпиксел одновременно входит в 3 полных пикселя. Такое изображение почти невозможно отличить от натурального при выводе на экран. Даже больше - в этом и есть залог натуральности (или как бы сейчас сказали - ламповости).

Разбор цепочки фильтров.
  1. Сначала получается нужное разрешение, но с размером, умноженным на размер субпиксельной сетки внутри пикселя (этот шаг обязателен, хоть с патентами, хоть без). В моём случае - zscale из zimg оказался быстрее встроенного scale.
  2. Субпиксели сводятся за счёт смещения соответствующих каналов. Есть два способа: rgbashift и convolution, из которых rgbashift - быстрее (в варианте с imagemagick используется конволюция).
  3. Размываем на ширину пикселя - должны охватываться все цветовые конпоненты. В нашем случае используется просто уменьшается разрешение методом area - что аналогично пикселизации и последующему сведению методом neighbor. К сожалению, в zscale нет метода area.
Смещение каналов можно выполнить и после размытия, но тогда нужно размытие, т.к. центры каналов ещё не совмещены, и пикселизация тут не к месту. К сожалению, avgfilter и boxfilter отпадают, т.к. не поддерживают размытие по одной стороне - остаётся только convolution.

Код: Выделить всё

convolution=1 1 1:1 1 1:1 1 1:1 1 1:0mode=row:1mode=row:2mode=row:3mode=row
Также можно заменить бокс-фильтр на гаусс (gblur - минус к чёткости, зато ламповость до 80-го уровня).

Код: Выделить всё

gblur=sigma=1.0:sigmaV=0
Скорость

На моём железе - чистый ffmpeg вытягивает 6-7fps при просмотре 4k на 1600x900 без ускорения (есть vaapi, но нужный формат файла не поддерживается). К сожалению, у меня нет ни opencl ни cuda, поэтому протестировать заточенный под них вариант невозможно - могу только предположить, сколько они вытянут; mpv выдаёт ещё меньше (с теми же фильтрами), лучшее примение при таком подходе - остановить воспроизведение и смаковать отдельные кадры :) (как вариант - скриншотить на обои).

Аппаратное ускорение (нужно проверять)

Фильтрация с ускорением в основном та же, что и без. Среди фильтров ffmpeg есть варианты *_opencl и *_cuda, специально для соответствующех режимов ускорения. Однако не все эффекты в цепочки присутствуют в этом списке (точнее - только один, хотя могу ошибаться).

Что меняется:
  • Плагин rgbashift есть только в одном варианте, зато есть convolution_opencl и convolution_cuda есть. Обычный convolution на моём железе понижает fps сразу почти до 3. Однако ускоренные варианты, скорее всего, стоит попробовать.
  • Также добавляются дополнительные элементы - для загрузки в железо и выгрузки обратно.
  • Перед convolution - обязательно форсировать формат gbrp, т.к. он работает с компонентами цветовой модели, а с видео - на входе обычно YUV, так что разультат может быть совсем не тот.
  • Можно попробовать вариант avgblur вместо scale в режиме area.
Параметры ffmpeg для opencl со всеми вариантами:

Код: Выделить всё

-hwaccel opencl
...
-vf "
  zscale=3*$w:$h:filter=bilinear,
  format=gbrp,
  hwupload,
  convolution_opencl=2m=1 1 1 0 0:0m=1 1 1:1m=0 0 1 1 1:1 1 1:0mode=row:1mode=row:2mode=row:3mode=row,
  hwdownload,
  scale=$w:$h:flags=neighbor"
Для mpv - к сожалению, перенос строк в его конфиге не работает (придётся терпеть).

Код: Выделить всё

vf=zscale=3*1600:900:filter=bilinear,format=gbrp,hwupload,convolution_opencl=2m="1 1 1 0 0":0m="1 1 1":1m="0 0 1 1 1":"1 1 1":0mode=row:1mode=row:2mode=row:3mode=row,hwdownload,scale=1600:900:flags=neighbor
Для cuda, к сожалению, никаких полезных плагинов с суффиксами.

Если с OpenCL заработает - поделитесь результатами :)
_______________________________________
С cuda тоже интересно, хотя я так понял - где cuda, там и opencl.
Фильтр program_opencl мог бы пригодиться, если под него написать чего-нибудь.
Спасибо сказали: