umlaeute / v4l2loopback

v4l2-loopback device
GNU General Public License v2.0
3.74k stars 531 forks source link

Failed to stream H264 to virtual camera: "does not support 2:4:7:1 colorimetry" #557

Open thilindaEdiri opened 1 year ago

thilindaEdiri commented 1 year ago

My environment

Problem Description:

I am trying to stream my USB cam video in H264 format to virtual camera using GStreamer. But i am getting error: does not support 2:4:7:1 colorimetry. My USB cam (Arducam USB Camera: Arducam USB) support H264 video format.

Trying to stream H264 video from USB camera (/dev/video2) to virtual camera (/dev/video10):

gst-launch-1.0 -v v4l2src device=/dev/video2 ! video/x-h264,width=640,height=480,framerate=30/1 ! v4l2sink device=/dev/video10

Gets Following error:

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Device '/dev/video2' does not support 2:4:7:1 colorimetry
Additional debug info:
gstv4l2object.c(3849): gst_v4l2_object_set_format_full (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
Device wants 2:4:5:1 colorimetry
Execution ended after 0:00:00.019369981
Setting pipeline to NULL ...
Freeing pipeline ...

Trying to get raw video from USB camera (/dev/video0) and convert to H264 and stream to virtual camera (/dev/video10): gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoscale ! videoconvert ! x264enc ! h264parse ! video/x-h264,stream-format=avc,alignment=au,width=640,height=480,framerate=30/1 ! v4l2sink device=/dev/video10

Gets Following error:

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
/GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)YUY2, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:5:1, interlace-mode=(string)progressive
/GstPipeline:pipeline0/GstVideoScale:videoscale0.GstPad:src: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)YUY2, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:5:1, interlace-mode=(string)progressive
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)Y42B, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive
Redistribute latency...
/GstPipeline:pipeline0/GstX264Enc:x264enc0.GstPad:sink: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)Y42B, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)YUY2, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:5:1, interlace-mode=(string)progressive
/GstPipeline:pipeline0/GstVideoScale:videoscale0.GstPad:sink: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)YUY2, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:5:1, interlace-mode=(string)progressive
/GstPipeline:pipeline0/GstX264Enc:x264enc0.GstPad:src: caps = video/x-h264, codec_data=(buffer)017a001effe1001d677a001ebcd940a03db016a0c040a8000003000800000301e478b16cb001000568ebecb22c, stream-format=(string)avc, alignment=(string)au, level=(string)3, profile=(string)high-4:2:2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601, chroma-site=(string)jpeg
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, codec_data=(buffer)017a001effe1001d677a001ebcd940a03db016a0c040a8000003000800000301e478b16cb001000568ebecb22c, stream-format=(string)avc, alignment=(string)au, level=(string)3, profile=(string)high-4:2:2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601, chroma-site=(string)jpeg, parsed=(boolean)true
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:sink: caps = video/x-h264, codec_data=(buffer)017a001effe1001d677a001ebcd940a03db016a0c040a8000003000800000301e478b16cb001000568ebecb22c, stream-format=(string)avc, alignment=(string)au, level=(string)3, profile=(string)high-4:2:2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601, chroma-site=(string)jpeg
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Additional debug info:
../subprojects/gstreamer/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
Execution ended after 0:00:02.491361422
Setting pipeline to NULL ...
Freeing pipeline ...

Successful when trying to stream raw video from /dev/video0 to virtual camera /dev/video10

gst-launch-1.0 -v v4l2src device=/dev/video0 ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! videoconvert ! v4l2sink device=/dev/video10

Result of gst-device-monitor-1.0:

Device found:

    name  : Arducam USB Camera: Arducam USB
    class : Video/Source
    caps  : video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)5/1;
            video/x-raw, format=(string)YUY2, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)10/1;
            video/x-raw, format=(string)YUY2, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 10/1, 5/1 };
            video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            image/jpeg, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            image/jpeg, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            image/jpeg, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 20/1, 15/1, 10/1, 5/1 };
            image/jpeg, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            image/jpeg, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
    properties:
        udev-probed = true
        device.bus_path = pci-0000:00:14.0-usb-0:1:1.0
        sysfs.path = /sys/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/video4linux/video0
        device.bus = usb
        device.subsystem = video4linux
        device.vendor.id = 0c45
        device.vendor.name = "Arducam\\x20Technology\\x20Co.\\x2c\\x20Ltd."
        device.product.id = 6366
        device.product.name = "Arducam\ USB\ Camera:\ Arducam\ USB"
        device.serial = Arducam_Technology_Co.__Ltd._Arducam_USB_Camera_UC684
        device.capabilities = :capture:
        device.api = v4l2
        device.path = /dev/video0
        v4l2.device.driver = uvcvideo
        v4l2.device.card = "Arducam\ USB\ Camera:\ Arducam\ USB"
        v4l2.device.bus_info = usb-0000:00:14.0-1
        v4l2.device.version = 331636 (0x00050f74)
        v4l2.device.capabilities = 2225078273 (0x84a00001)
        v4l2.device.device_caps = 69206017 (0x04200001)
    gst-launch-1.0 v4l2src ! ...

Device found:

    name  : Arducam USB Camera: Arducam USB
    class : Video/Source
    caps  : video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 20/1, 15/1, 10/1, 5/1 };
            video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1 };
            video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 };
    properties:
        udev-probed = true
        device.bus_path = pci-0000:00:14.0-usb-0:1:1.0
        sysfs.path = /sys/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/video4linux/video2
        device.bus = usb
        device.subsystem = video4linux
        device.vendor.id = 0c45
        device.vendor.name = "Arducam\\x20Technology\\x20Co.\\x2c\\x20Ltd."
        device.product.id = 6366
        device.product.name = "Arducam\ USB\ Camera:\ Arducam\ USB"
        device.serial = Arducam_Technology_Co.__Ltd._Arducam_USB_Camera_UC684
        device.capabilities = :capture:
        device.api = v4l2
        device.path = /dev/video2
        v4l2.device.driver = uvcvideo
        v4l2.device.card = "Arducam\ USB\ Camera:\ Arducam\ USB"
        v4l2.device.bus_info = usb-0000:00:14.0-1
        v4l2.device.version = 331636 (0x00050f74)
        v4l2.device.capabilities = 2225078273 (0x84a00001)
        v4l2.device.device_caps = 69206017 (0x04200001)
    gst-launch-1.0 v4l2src device=/dev/video2 ! ...

I also tried with v4l2loopback versions 0.12.6, 0.12.7 and gstreamer version 1.18.6. But same errors.

I would appreciate a prompt response.

Thank you.

umlaeute commented 1 year ago

could you try with current main (9ba7e294ea6f45410a15f192381d4918e8df4f02)?

i cannot fully reproduce the problem (having no hardware that natively speaks h264), however:

the following pipeline appears to work for me with v0.12.7 and current main:

gst-launch-1.0 -v videotestsrc \
! x264enc \
! h264parse \
! "video/x-h264,width=640,height=480,pixel-aspect-ratio=1/1,framerate=30/1,interlace-mode=progressive,colorimetry=2:4:7:1" \
! v4l2sink device=/dev/video2

however, the following pipeline fails from me with v0.12.7 (note the "colorimetry=bt601")

gst-launch-1.0 -v videotestsrc \
! x264enc \
! h264parse \
! "video/x-h264,width=640,height=480,pixel-aspect-ratio=1/1,framerate=30/1,interlace-mode=progressive,colorimetry=bt601" \
! v4l2sink device=/dev/video2

however, the above pipeline appears to work with main

thilindaEdiri commented 1 year ago

Hi @umlaeute,

Thank you for your response.

I tried with v4l2loopback v0.12.7 (https://github.com/umlaeute/v4l2loopback/commit/9ba7e294ea6f45410a15f192381d4918e8df4f02) with following pipeline (/dev/video10 is the virtual camera).

gst-launch-1.0 -v videotestsrc \
! x264enc \
! h264parse \
! "video/x-h264,width=640,height=480,pixel-aspect-ratio=1/1,framerate=30/1,interlace-mode=progressive,colorimetry=2:4:7:1" \
! v4l2sink device=/dev/video10

I get the following error.

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0.GstPad:src: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, pixel-aspect-ratio=(fraction)1/1, format=(string)Y444, multiview-mode=(string)mono, interlace-mode=(string)progressive
Redistribute latency...
/GstPipeline:pipeline0/GstX264Enc:x264enc0.GstPad:sink: caps = video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, pixel-aspect-ratio=(fraction)1/1, format=(string)Y444, multiview-mode=(string)mono, interlace-mode=(string)progressive
/GstPipeline:pipeline0/GstX264Enc:x264enc0.GstPad:src: caps = video/x-h264, codec_data=(buffer)01f4001effe1001d67f4001e919b281407b602d41808150000030001000003003c8f162d9601000568ebec4480, stream-format=(string)avc, alignment=(string)au, level=(string)3, profile=(string)high-4:4:4, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601, chroma-site=(string)jpeg, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, codec_data=(buffer)01f4001effe1001d67f4001e919b281407b602d41808150000030001000003003c8f162d9601000568ebec4480, stream-format=(string)avc, alignment=(string)au, level=(string)3, profile=(string)high-4:4:4, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601, chroma-site=(string)jpeg, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, parsed=(boolean)true
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:sink: caps = video/x-h264, codec_data=(buffer)01f4001effe1001d67f4001e919b281407b602d41808150000030001000003003c8f162d9601000568ebec4480, stream-format=(string)avc, alignment=(string)au, level=(string)3, profile=(string)high-4:4:4, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601, chroma-site=(string)jpeg, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono
ERROR: from element /GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0: Internal data stream error.
Additional debug info:
../subprojects/gstreamer/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0:
streaming stopped, reason not-negotiated (-4)
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...

For the following pipeline:

gst-launch-1.0 -v v4l2src device=/dev/video2 ! video/x-h264,width=640,height=480,framerate=30/1 \
 ! h264parse ! v4l2sink device=/dev/video10 

I get the following error:

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Device '/dev/video2' does not support 2:0:0:0 colorimetry
Additional debug info:
gstv4l2object.c(3849): gst_v4l2_object_set_format_full (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
Device wants 2:4:5:1 colorimetry
Execution ended after 0:00:00.175808594
Setting pipeline to NULL ...
Freeing pipeline ...

For the following pipeline:

gst-launch-1.0 -v v4l2src device=/dev/video2 \
 ! "video/x-h264,width=640,height=480,framerate=30/1,pixel-aspect-ratio=1/1,interlace-mode=progressive,colorimetry=2:4:5:1" \ 
 ! h264parse ! v4l2sink device=/dev/video10 

I get the following error:

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Additional debug info:
../subprojects/gstreamer/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
Execution ended after 0:00:00.000449644
Setting pipeline to NULL ...
Freeing pipeline ...

Is it possible that the outcome can be changed based on the Linux distribution or the kernel version?

Because i want to run this on Jetson Orin with Ubuntu 20.04 installed. It also get the same errors as my laptop.

umlaeute commented 1 year ago

rather than the Linux kernel version i would imagine that the GStreamer version matters.

I'm using gstreamer_1.22.6-1 (on my Debian/sid machine).

Newer Linux distributions will have newer versions of the packaged software, which in turn will have bugs fixed (and new bugs)

samhurst commented 1 week ago

Apologies for reviving a year-old thread, but I'm having this exact same issue. I'm receiving video from a remote IP source, decoding it and then trying to present it as a webcam device within a web app. However, whenever I try to link the video decoder and the v4l2sink element it fails to link the pipeline because it can't match the colorimetry caps parameter between my decoder pipeline and the sink. In my case, the colorimetry caps parameter is set as "2:4:7:1".

I've done some digging and discovered that the 2:4:7:1 string comes from the gst_video_colorimetry_to_string function failing to understand the GstVideoColorimetry structure passed in. The reason for this is that in GStreamer's view, sRGB is always full range, whereas the v4l2loopback driver seems to use limited range (and thus the 2 in the colorimetry string).

Reading the v4l2 docs, it seems to imply that sRGB should be limited range by default - so am I misunderstanding something or is GStreamer wrong to assert that sRGB can only ever be full range?

I'm using Ubuntu 24.04, kernel 6.8.12, v4l2loopback version 0.12.7 (from Ubuntu repositories) and GStreamer 1.25.0 from git (as of a couple of days ago).