Как использовать ffmpeg с кодировщиком mjpeg_vaapi (с аппаратным ускорением)?
Когда я использую ffmpeg с кодировщиком mjpeg без аппаратного ускорения, все работает нормально. Я использую следующую команду:
ffmpeg -nostdin -rtsp_transport udp_multicast -allowed_media_types 'video' -i 'rtsp://MYIP' -ss 00:00:0.00 -f image2pipe -q:v 24 -vf scale=-2:480,format=yuv420p -c:v mjpeg -vframes 1 pipe:1
Но когда я пытаюсь использовать mjpeg с аппаратным ускорением, я всегда получаю ошибку:
ffmpeg -nostdin -rtsp_transport udp_multicast -allowed_media_types 'video' -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i 'rtsp://MYIP' -ss 00:00:0.00 -f image2pipe -q:v 24 -vf scale=-2:480,format=yuv420p -c:v mjpeg_vaapi -vframes 1 pipe:1
ffmpeg version N-91514-gc51e0cd Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 20160609
configuration: --pkg-config-flags=--static
libavutil 56. 18.102 / 56. 18.102
libavcodec 58. 21.106 / 58. 21.106
libavformat 58. 17.101 / 58. 17.101
libavdevice 58. 4.101 / 58. 4.101
libavfilter 7. 26.100 / 7. 26.100
libswscale 5. 2.100 / 5. 2.100
libswresample 3. 2.100 / 3. 2.100
libva info: VA-API version 0.39.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
Input #0, rtsp, from 'rtsp://MYIP':
Metadata:
title : Session streamed with GStreamer
comment : rtsp-server
Duration: N/A, start: 0.180600, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuvj420p(pc, progressive), 800x600, 50 fps, 50 tbr, 90k tbn, 100 tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (mjpeg_vaapi))
Impossible to convert between the formats supported by the filter 'graph 0 input from stream 0:0' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while processing the decoded data for stream #0:0
Conversion failed!
Я попытался с некоторыми дополнительными опциями, но он все еще не работает:
ffmpeg -nostdin -rtsp_transport udp_multicast -allowed_media_types 'video' -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i 'rtsp://MYIP' -ss 00:00:0.00 -f image2pipe -q:v 24 -vf "scale_vaapi=w=800:h=600" -b:v 700k -r 25 -vcodec mjpeg_vaapi -vframes 1 pipe:1
ffmpeg version N-91514-gc51e0cd Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 20160609
configuration: --pkg-config-flags=--static
libavutil 56. 18.102 / 56. 18.102
libavcodec 58. 21.106 / 58. 21.106
libavformat 58. 17.101 / 58. 17.101
libavdevice 58. 4.101 / 58. 4.101
libavfilter 7. 26.100 / 7. 26.100
libswscale 5. 2.100 / 5. 2.100
libswresample 3. 2.100 / 3. 2.100
libva info: VA-API version 0.39.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
Input #0, rtsp, from 'rtsp://MYIP':
Metadata:
title : Session streamed with GStreamer
comment : rtsp-server
Duration: N/A, start: 0.179933, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuvj420p(pc, progressive), 800x600, 50 fps, 50 tbr, 90k tbn, 100 tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (mjpeg_vaapi))
[mjpeg_vaapi @ 0x374cd80] Encoding entrypoint not found (12 / 7).
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
Conversion failed!
Может кто-нибудь предложить правильные варианты, чтобы это работало?
2 ответа
Поэтому проблема была в том, что моя платформа Intel CPU была старой (Broadwell), и кодировка JPEG поддерживается начиная с Braswell. Пожалуйста, посмотрите все поддерживаемые кодеки на платформе на странице
После запуска той же команды на машине с процессором Skylake, она работает с первой попытки:)
Когда вы пытаетесь использовать аппаратное кодирование Intel, вам нужно проверить ДВЕ вещи.
- скорее ваш конкретный Intel поддерживает кодировщик, который вы хотите
- скорее ваш двоичный файл ffmpeg откуда-то скомпилирован с библиотекой аппаратного ускорения или нет.
Чтобы узнать, какой тип кодировщика поддерживает ваш Intel, вы просто набираете:
vainfo|grep -i enc
в нем будет указан кодировщик, который поддерживает ваш процессор. В моем случае, например, это дает следующее:
libva info: VA-API version 1.13.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_13
libva info: va_openDriver() returns 0
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileHEVCMain : VAEntrypointEncSlice
в моем случае мой процессор Intel поддерживает кодировку mjpeg.
если вы не можете найти ничего похожего на mjpeg, тогда вы можете отказаться от идеи использования аппаратного ускорения Intel для достижения того, что вы хотите на этой машине.
Следующее, что вам нужно, это выяснить, в первую очередь, ваш двоичный файл ffmpeg поддерживает Intel vaapi. Сначала нужно ввести:
ffmpeg -hide_banner -hwaccels
если в одной из этих строк есть « vaapi », это означает, что ffmpeg скомпилирован с библиотекой аппаратного ускорения Intel. Если ваша команда vainfo имеет то, что вы хотите, но приведенная выше команда не отображает vaapi, вам нужно получить еще одну копию двоичного файла ffmpeg. либо из другого источника, либо скомпилируйте его самостоятельно.
Далее нужно перечислить все кодировщики ffmpeg, которые на самом деле используют vaapi, и надеяться, что один из них похож на mjpeg:
ffmpeg -hide_banner -encoders|grep -i vaapi
В моем случае у меня есть:
V....D h264_vaapi H.264/AVC (VAAPI) (codec h264)
V....D hevc_vaapi H.265/HEVC (VAAPI) (codec hevc)
V....D mjpeg_vaapi MJPEG (VAAPI) (codec mjpeg)
V....D mpeg2_vaapi MPEG-2 (VAAPI) (codec mpeg2video)
V....D vp8_vaapi VP8 (VAAPI) (codec vp8)
V....D vp9_vaapi VP9 (VAAPI) (codec vp9)
Так что в моем случае энкодер есть.
если и vainfo, и ffmpeg -hwaccels дают то, что вам нужно, но этот последний шаг не дает, то вам нужно откуда-то получить еще один двоичный файл ffmpeg.
удачи.