Stream static image to v4l2loopback using obs with v4l2 plugin, ffmpeg or gstreamer

2.9k views Asked by At

I want to stream a static image to the android studio emulator. To do that I created a virtual camera using v4l2loopback v.12.5 in linux ubuntu 20.04. The virtual camera is created in /dev/video2. I can stream there using obs and a plugin, ffmpeg or gstreamer but I've got different issues with each one. I don't care which software works... I always use an image with the resolution 1920x1080 to test this.

OBS: I installed the obs plugin following this tutorial here. It explains how to install v4l2loopback and add the plugin to obs. The plugin is called obs-v4l2sink. I start v4l2loopback using this command:

sudo modprobe v4l2loopback exclusive_caps=1 video_nr=2 card_label=virtualCam

and then:

v4l2loopback-ctl set-caps "video/x-raw, format=NV12, width=1920, height=1080" "/dev/video2"

Then I start Obs with the base canvas 1920x1080 and output 1920x1080 too. In the plugin I choose NV12 as the video format and /dev/video2 as the V4L2 Device. The image is successfully sent to the emulator but the resolution is wrong. Using ffplay I get this message:

"Input #0, video4linux2,v4l2, from '/dev/video2':B sq= 0B f=0/0 Duration: N/A, start: 1650.347834, bitrate: 27648 kb/s Stream #0:0: Video: rawvideo (NV12 / 0x3231564E), nv12, 320x240, 27648 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc"

It seems, that the resolution is scaled down to 320x240 and I have no clue why.

ffmpeg: I can stream to /dev/video2 with ffmpeg using this command:

ffmpeg -re loop 1 -i licensePlate.png -f v4l2 /dev/video2 

But I only get wrong pixels in ffplay, which outputs this:

[video4linux2, v4l2 @ 0x7fb494000bc0] Dequeued v4l2 buffer contains 118784 bytes, but 115200 were expected. Flags: 0x00000001.

Gstreamer: Gstreamer only works if I don't use the following command after the modprobe (If I use it, the pipeline is blocked for Gstreamer):

v4l2loopback-ctl set-caps "video/x-raw, format=NV12, width=1920, height=1080" "/dev/video2"

Instead I call this command:

gst-launch-1.0 -v multifilesrc location=licensePlate2.png loop=1 caps="image/png,framerate=10/1" ! pngdec ! videoscale ! videoconvert ! "video/x-raw,format=NV12,width=1920,height=1080" ! v4l2sink device=/-dev/video2

Using ffplay I see the image I desire in 1920x1080 and everything seems fine, but in the android studio emulator I only get a weird greenscreen. I got this greenscreen before and I think it has got something to do with a wrong resolution. I don't really know what is wrong here. The emulator shows these logs many times:

emulator: ERROR: camera_device_start_capturing: Dimensions 0x0 are wrong for pixel format NV12
emulator: ERROR: _camera_client_start: Cannot start camera '/dev/video2' for NV12[0x0]: Inappropriate ioctl for device

The avd I'm using is Pixel2 1920x1080 Android 11 x86 64 and I'm starting it using this command:

./emulator -avd Pixel264 -camera-back webcam1 -no-snapshot
Pixel264 is my avd and webcam1 is the virtual webcam, that is linked to /dev/video2
1

There are 1 answers

1
ykasur On BEST ANSWER

I just tried it with Android Studio Emulator API 28 (Google X86_ARM) and it works. So it seems that it is related to the CPU Architecture of the emulator and x86 64 does not work. I needed arm though and thankfully Google added Arm translation to an image in Api 28.

It seems that only images with resolution 1920x1080 work, but maybe it is only related to the ratio.

Obs does not work now for some reason but this command works perfectly: ffmpeg -loop 1 -re -i licensePlate2.png -f v4l2 -vcodec rawvideo -pixfmt nv12 -vf transpose=4 /dev/video2