Моя цель: получить поток, кодированный в h264 из веб-камеры Logitech c920. Я примерно представляю, сколько раз разжевывался этот вопрос в интернетах, но ничего не получается. Что есть: Ubuntu 19.04 на ноуте Vaio SVS1513, собственно c920. Вывод v4l-ctl:
user@vaio:~$ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
user@vaio:~$ v4l2-ctl --all
Driver Info (not using libv4l2):
Driver name : uvcvideo
Card type : HD Pro Webcam C920
Bus info : usb-0000:00:14.0-3
Driver version: 4.18.20
Capabilities : 0x84A00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
Width/Height : 800/600
Pixel Format : 'YUYV'
Field : None
Bytes per Line : 1600
Size Image : 960000
Colorspace : sRGB
Transfer Function : Default (maps to sRGB)
YCbCr/HSV Encoding: Default (maps to ITU-R 601)
Quantization : Default (maps to Limited Range)
Flags :
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 800, Height 600
Default : Left 0, Top 0, Width 800, Height 600
Pixel Aspect: 1/1
Selection: crop_default, Left 0, Top 0, Width 800, Height 600
Selection: crop_bounds, Left 0, Top 0, Width 800, Height 600
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 24.000 (24/1)
Read buffers : 0
brightness 0x00980900 (int) : min=0 max=255 step=1 default=128 value=128
contrast 0x00980901 (int) : min=0 max=255 step=1 default=128 value=128
saturation 0x00980902 (int) : min=0 max=255 step=1 default=128 value=128
white_balance_temperature_auto 0x0098090c (bool) : default=1 value=1
gain 0x00980913 (int) : min=0 max=255 step=1 default=0 value=223
power_line_frequency 0x00980918 (menu) : min=0 max=2 default=2 value=2
white_balance_temperature 0x0098091a (int) : min=2000 max=6500 step=1 default=4000 value=3193 flags=inactive
sharpness 0x0098091b (int) : min=0 max=255 step=1 default=128 value=128
backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=0 value=0
exposure_auto 0x009a0901 (menu) : min=0 max=3 default=3 value=3
exposure_absolute 0x009a0902 (int) : min=3 max=2047 step=1 default=250 value=415 flags=inactive
exposure_auto_priority 0x009a0903 (bool) : default=0 value=1
pan_absolute 0x009a0908 (int) : min=-36000 max=36000 step=3600 default=0 value=0
tilt_absolute 0x009a0909 (int) : min=-36000 max=36000 step=3600 default=0 value=0
focus_absolute 0x009a090a (int) : min=0 max=250 step=5 default=0 value=30 flags=inactive
focus_auto 0x009a090c (bool) : default=1 value=1
zoom_absolute 0x009a090d (int) : min=100 max=500 step=1 default=100 value=100
user@vaio:~$ v4l2-ctl --list-devices
HD Pro Webcam C920 (usb-0000:00:14.0-3):
/dev/video0
/dev/video1
USB2.0 Camera: USB2.0 Camera (usb-0000:00:1a.0-1.3):
/dev/video2
/dev/video3
Дальше пытаюсь действовать по мануалу с
хабра, но ни uvch264src, ни v4l2src, ни vlc не хотят работать с камерой в качестве источника h264.
cvlc:
user@vaio:~$ v4l2-ctl --device=/dev/video0 --set-fmt-video=width=800,height=600,pixelformat=1
user@vaio:~$ cvlc v4l2:///dev/video0:chroma=h264:width=800:height=600 --sout '#standard{access=http,mux=ts,dst=localhost:8080,name=stream,mime=video/ts}' -vvv
... skip ...
[00007fe8e0000c40] main input debug: `v4l2:///dev/video0:chroma=h264:width=800:height=600' successfully opened
[00007fe8e0000c40] main input debug: Buffering 0%
[00007fe8e0000c40] main input debug: switching to sync mode
[00007fe8dc0015e0] main stream output debug: adding a new sout input for `YUY2` (sout_input: 0x7fe8d4000b20)
[00007fe8dc005130] main mux debug: adding a new input
[00007fe8dc005130] mux_ts mux warning: rejecting stream with unsupported codec YUY2
[00007fe8dc005130] main mux error: cannot add this stream
[00007fe8dc0015e0] main stream output warning: new sout input failed (sout_input: 0x7fe8d4000b20)
[00007fe8dc4da2a0] main decoder error: cannot create packetizer output (YUY2)
... skip ...
Как я понял, это от несоответствия ожидаемого формата (h264) и получаемого фактически (raw YUY2).
uvch264src:
user@vaio:~$ gst-launch-1.0 -v -e uvch264src device=/dev/video0 name=src auto-start=true src.vfsrc ! queue ! video/x-raw,format=YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false
Установка конвейера в состояние PAUSED…
ОШИБКА: Конвейер не хочет становиться на паузу.
/GstV4l2Src:v4l2src0: num-buffers = -1
/GstV4l2Src:v4l2src0: device = /dev/video0
ОШИБКА: из элемента /GstPipeline:pipeline0/GstUvcH264Src:src: Device is not a valid UVC H264 camera
Дополнительная отладочная информация:
gstuvch264_src.c(2528): ensure_v4l2src (): /GstPipeline:pipeline0/GstUvcH264Src:src
Установка конвейера в состояние NULL…
Освобождение конвейера…
v4l2src:
user@vaio:~$ gst-launch-1.0 -v -e v4l2src device=/dev/video0 ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false
Установка конвейера в состояние PAUSED…
Конвейер работает и не требует состояния PREROLL…
Установка конвейера в состояние PLAYING…
New clock: GstSystemClock
ОШИБКА: из элемента /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Дополнительная отладочная информация:
gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
Включён EOS при закрытии — ожидание EOS после ошибки
Ожидание EOS…
^Chandling interrupt.
Прерывание: Остановка конвейера…
Прерывание во время ожидания EOS — остановка конвейера…
Execution ended after 0:00:03.536119652
Установка конвейера в состояние PAUSED…
Установка конвейера в состояние READY…
Установка конвейера в состояние NULL…
Освобождение конвейера…
В интернетах говорят, что reason not-negotiated (-4) это опять же несоответствие ожидаемого и получаемого форматов.
ffmpeg я тоже пробовал, он тоже выдает два вида форматов - raw и mjpeg, а поскольку я не понял, исправлен ли баг со сбросом формата на raw при подключении к девайсу, то я сильно в эту сторону не копал.
Куда бечь, господа? Если я ничего не понял, c920 может показывать формат/пин/пад/яхз h264, а может не показывать, при этом упаковывая данные h264 в поток mjpeg. Во втором случае должен работать uvch264src, он для этого создавался (наверно). В первом должно работать вообще все, но нет. Как заставить c920 выдавать h264? Вариант кодировать извне мне не подходит, т.к. в итоге хочу получать поток на onion S2+, а там аппаратного кодека (или я о нем не знаю).