FFMPEG перекодирует видео H265 из 10-битного в 8-битное
Я пытаюсь преобразовать свою библиотеку из различных форматов в 8-битный HEVC, в основном, чтобы уменьшить размер моей библиотеки. Обычно это работает, но я столкнулся с проблемой при попытке преобразовать существующий файл из 10-битного H.265 в 8-битный H.265.
Мой процессор Intel Celeron J3455 поддерживает аппаратное декодирование / кодирование H.265 в 8-битном формате, но только аппаратное декодирование для 10-битного.
Похоже, что ffmpeg пытается сохранить видео как 10-битное, чтобы соответствовать источнику, а не позволяет мне преобразовать в 8-битное, и это создает ошибку.
Вот пример команды, которую я использую:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.10bit.x265.mkv -map 0:0 -c:v:0 hevc_vaapi -vf "scale_vaapi=w=-1:h=1080" -b:v 4027047 -map 0:1 -c:a:0 aac -b:a 384000 -ac 6 -map 0:s -scodec copy -map_metadata:g -1 -metadata JBDONEVERSION=1 -metadata JBDONEDATE=2020-06-06T20:52:36.072Z -map_chapters 0 output.8bit.x265.mkv
Я получаю следующую ошибку:
[hevc_vaapi @ 0x5568b27fb1c0] No usable encoding entrypoint found for profile VAProfileHEVCMain10 (18).
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Насколько я могу судить, ffmpeg смотрит на источник и выбирает VAProfileHEVCMain10 вместо VAProfileHEVCMain. Я бы хотел, чтобы он выводил 8 бит.
Я пробовал добавить -pix_fmt yuv420p
но это дает мне эту ошибку:
Incompatible pixel format 'yuv420p' for codec 'hevc_vaapi', auto-selecting format 'vaapi_vld'
Я также пробовал внести это изменение в команду: "scale_vaapi=w=-1:h=1080,format=yuv420p"
Однако это дает мне ошибку:
Impossible to convert between the formats supported by the filter 'Parsed_scale_vaapi_0' and the filter 'auto_scaler_0'
Error reinitializing filters!
Какие-либо предложения?
1 ответ
Я только что понял это, а также. Ваша проблема (скорее всего) с
-hwaccel_output_format vaapi
. Он выводит кадры в формате VAAPI, а не в том формате, который вам нужен (подробнее здесь, также процитирован раздел в конце этого комментария). Так что вам нужно настроить на 8-бит там:
-hwaccel_output_format yuv420p
.
В моем случае я также использую
-filter_hw_device vaapi0 -vf format=nv12|vaapi,hwupload
(указано перед
-c:v hevc_vaapi
). В
vaapi0
вот именованное устройство, с которым я инициализировался
init_hw_device
. Вы напрямую используете путь с
-hwaccel_device
поэтому я не уверен, как называется ваше устройство, но вам могут не понадобиться эти дополнительные аргументы.
Аппаратные кодеки, используемые VAAPI, не могут получить доступ к данным кадра в произвольной памяти. Таким образом, перед использованием все данные кадра должны быть загружены на аппаратные поверхности, подключенные к соответствующему устройству. Все аппаратные поверхности VAAPI в ffmpeg представлены vaapi pixfmt (однако внутренняя компоновка здесь не видна).
Декодеры hwaccel обычно выводят кадры в соответствующем аппаратном формате, но по умолчанию утилита ffmpeg загружает выходные кадры в обычную память перед передачей их следующему компоненту. Это позволяет декодеру работать автономно, чтобы ускорить декодирование без каких-либо дополнительных опций:
ffmpeg -hwaccel vaapi ... -i input.mp4 -c:v libx264 ... output.mp4
Для других выходных данных можно использовать параметр -hwaccel_output_format, чтобы указать используемый формат. Это может быть программный формат (какие форматы можно использовать, зависит от драйвера) или аппаратный формат vaapi, указывающий, что поверхность не следует загружать.