Как использовать 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, вам нужно проверить ДВЕ вещи.

  1. скорее ваш конкретный Intel поддерживает кодировщик, который вы хотите
  2. скорее ваш двоичный файл 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.

удачи.

Другие вопросы по тегам