Menu

#125 Red and Blue channels swapped when streaming output to Google Chrome

0.73
Fixed
Tetsujin
None
Medium
Linux
Unspecified
Defect
2016-03-11
2015-06-01
Tetsujin
No

What steps will reproduce the problem?
1. Load v4l2loopback module (I'm using v0.8.0)
2. Run WCS, set up some kind of input and set the V4L2 loopback "Dummy Video Device" as the output
3. Open the loopback device in Google Chrome (go to testmywebcam.net, Google Hangouts, etc. to view the WCS stream)

What is the expected output?
Display in the other application should match the preview in WCS

What do you see instead?
red and blue color channels appear to be swapped. Swapping the color channels from within WCS (via the SwapRedBlue FX filter) makes the video shown in Chrome look correct.

The Operating system you are using (Linux, Windows etc)?
Linux (Debian stable + testing)

What version of WebcamStudio are you using?
0.73 build 584

What version of Java are you using?
java version "1.7.0_75"
OpenJDK Runtime Environment (IcedTea 2.5.4) (7u75-2.5.4-2)
OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)

What is your Webcamera vendor, model and version?
Lenovo Thinkpad x220T integrated camera
Sony DCR-TRV17 DV camera connected via Firewire

For *nix users please enter the output from "sudo lsusb"?
Bus 003 Device 005: ID 04f2:b217 Chicony Electronics Co., Ltd Lenovo Integrated Camera (0.3MP)

I don't know whether this is actually a problem with WCS or with Chrome. But I've tried viewing the WCS stream with other programs (VLC, ekiga, Firefox/Adobe Flash, mplayer, xawtv, etc.) and they all get it right - so it's seems likely that is the case. But I'm not entirely sure.

Just to add another nail in the coffin, I edited libwebcamstudio.c and changed the output mode from RGB to BGR, to see if that would solve the problem in Chrome. (Theory being, maybe VLC was getting the media format from the stream itself, while Google Chrome was getting it from the video device... Changing the setting on the video device would then presumably result in VLC being unchanged, and Chrome being fixed...) But Chrome's behavior was unchanged, and VLC, mplayer, etc. all showed color-swapped video... Which appears to indicate that these other programs are getting their pixel format from the stream, and Google Chrome is just assuming BGR24.

If we view this as a problem in Chrome, it might still be worth considering workarounds - right now I can work around the problem with the SwapRedBlue FX filter, but it must be applied separately not only to all sources, but to all sources in all channels as well. Working around the issue would be much simpler if FX could be applied to the output end of the pipeline as well.

On the bright side - I've got WCS working in Chrome. That's good news. :)

Discussion

  • Soylent TV

    Soylent TV - 2015-06-01

    Thanks George,
    I confirm the problem and the workaround.
    I think it is a good idea to have a Swap red/blue FX applied at the WS output, and also i was thinking of a Master Audio slider, but have little time.
    If you want to join the project, please let me know.
    Tanks.
    karl

     
  • Tetsujin

    Tetsujin - 2015-06-05

    I've discovered another wrinkle to this thing that may provide some insight:

    1: Launch WCS, produce some video over the loopback device
    2: Use VLC to open the loopback device for playback (colors will appear correct)
    3: Use VLC's "record" feature to capture video from the stream
    4: Play back the captured video. Red and blue will be swapped

    When recording straight from my webcam VLC's recordings don't exhibit this distortion. But so far I'm not sure what this means.

     
    • Soylent TV

      Soylent TV - 2015-06-07

      Hi George,
      I try this today and in my result the recorded video from WSVideoDevice (v4l2loopback fork) with VLC, i didn't noticed the issue.
      The recoded video colors looks ok.
      Have you also try with the WebcamStudio SkyCam feature recording /dev/video21 ?
      Thanks for the work.
      karl.

       
      • Tetsujin

        Tetsujin - 2015-06-07

        I hadn't had any success with the WSVideoDevice module previously. I just did a new build from SVN and after removing the vdev->debug lines (which caused compilation failure against my kernel, v4.0.2) it works.

        I can confirm that using the Skycam feature does resolve both the VLC recording feature and Google Chrome's red/blue swap issue: but the reason for this is because the gstreamer process is converting the RGB24 stream to YUV420 - quartering the color resolution in the process. VLC and Chrome are not manifesting their red/blue swap bugs in this case because the bugs are specific to RGB24 streams, and the stream is no longer RGB24.

        (I believe Chrome's bug stems from a mistaken belief that what V4L2 calls "RGB24" is equivalent to what Windows calls "RGB24". I believe the bug in VLC is similar a failure to properly encode the RGB24 byte ordering in the AVI file produced by the recording process.)

        Also, unfortunately, the process of getting Skycam mode working in Chrome is a bit complicated: Skycam mode works by sending WCS output to /dev/video1, and then using a Gstreamer process to pass that data from video1 to video21. But if Chrome attempts to open /dev/video1, it will succeed, and the Gstreamer process will stop, and thus /dev/video21 will stop working. This is a real problem for WCS, as Chrome's likely to find /dev/video1 before /dev/video21, and may even play it by default. (I think what's happening here is that V4L2loopback supports multiple clients reading a stream, but Google Chrome is sending VIDIOC_STREAMOFF prior to closing the device (see V4L2CaptureDelegate::StopAndDeallocate() in chromium-src/media/video/capture/linux/v4l2_capture_delegate.cc for details) - when /dev/video1 is stopped, gstreamer can't continue feeding video data to /dev/video21, so it terminates.)

        I don't know if v4l2loopback implements any controls that could prevent VIDIOC_STREAMOFF from killing the stream for all clients, or to prevent Chrome from opening /dev/video1 in the first place. It's possible there's an upstream bug there worth reporting. But generally, I think the policy of V4L2 drivers is that there are no specific requirements for how they handle cases like this.

        Anyway, the trick to getting Skycam mode to work in Chrome is to make sure it doesn't open /dev/video1 before opening /dev/video21 - or if it does (and gstreamer shuts down), relaunch gstreamer, go back to Chrome, and select /dev/video21 again.

        But the reason why Skycam mode is working in these cases is because it's providing YUV420 color data as opposed to RGB24, and the bugs we're facing in Chrome and VLC are specific to RGB24 data. It's not a bad way around the problem, more elegant than adding a "swap red/blue" option to the output, and it leaves people less likely to think this is a WCS bug. But the down-side is that YUV420 reduces the color resolution, degrading the image.

        But if we want to produce YUV420 output for Chrome, why use a gstreamer process and a second loopback device to do that? We've already got code for producing YUV420 data, and UYVY data. We could do that directly instead of writing out RGB and converting it. Or if there is real value to having gstreamer do the job, feed the data into gstreamer through a pipe or socket rather than a V4L2 loopback device.

         
  • Tetsujin

    Tetsujin - 2015-06-07

    I did some more digging, mostly looking for a good way to work around this issue on our end. I'm not sure there is one.

    Looking in the Chromium source (media/video/capture/linux/v4l2_capture_delegate.cc) it seems the only uncompressed formats Chrome will accept from a V4l2 device are RGB, YUV420, YUYV, and UYVY. We can encode to the YUV formats but that would mean (in addition to having to transform the data) chroma information would be passed in at half horizontal resolution.

    I had hoped Chrome would include support for BGR or RGB32, so I could try that and hopefully find it working better than RGB24. Alas, no.

    I suspect the issue in Chrome stems from the fact that "RGB24" on Windows is actually what Linux would call "BGR24" - blue, green, red in that order. (what the hell, Microsoft?) I think the issue I observed with VLC's record feature is something similar.

    So my plan from here is to give us a better workaround, probably a way to add red/blue swap just prior to output, rather than individually to all the inputs. Hopefully the Chrome folks will address this on their end.

     

    Last edit: Tetsujin 2015-06-07
    • Soylent TV

      Soylent TV - 2015-06-07

      I agree with you. It will be useful also a master Volume slider prior to output ... now i'm working on TrucklistStudio and when i finish i will begin that.
      Thanks.
      karl.

       
  • Tetsujin

    Tetsujin - 2015-06-07
    • assigned_to: George Caswell
     
  • Tetsujin

    Tetsujin - 2016-03-11
    • status: New --> Fixed
     
  • Tetsujin

    Tetsujin - 2016-03-11

    This was worked-around in WCS by providing the option to select different pixel formats for the output. Google Chrome now incorporates an upstream fix that corrects the issue, so using RGB mode for the loopback device now works as well.

     

Log in to post a comment.