0

I am using ffmpeg 4.2.2 on an Ubuntu 20.04 machine to clone the video stream of a USB webcam so that multiple applications can use the same feed. To achieve this, I simply clone to a v4l2 loop back device:

ffmpeg -f v4l2 -i /dev/video0 -codec copy -f v4l2 /dev/video1

So far, this works reasonably well. I am able to successfully access /dev/video1 which presents the same feed as /dev/video0. Note: To make this work you need to ensure that the v4l2loopback device kernel module is enabled:

modprobe v4l2loopback devices=1

Next I'd like to convert the pixel format of the dummy device as the application that is accessing the dummy device can only handle yuv422p or RGB whereas my source device /dev/video0 provides yuv420p. I thought that this would be a simple task that can easily be handled by presenting ffmpeg with an additional -pix_fmt argument on the output device like so:

ffmpeg -f v4l2 -i /dev/video0 -codec copy -f v4l2 -pix_fmt yuv422p /dev/video1

While ffmpeg starts cloning the stream without any warnings or errors, it is still outputting in yuv420p instead:

joel@joel-ubuntu:~$ ffmpeg -f v4l2 -i /dev/video0 -codec copy -f v4l2 -pix_fmt yuv422p /dev/video1
ffmpeg version 4.2.2-1ubuntu1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-3ubuntu1)
  configuration: --prefix=/usr --extra-version=1ubuntu1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
[video4linux2,v4l2 @ 0x55ca407b9700] Time per frame unknown
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 6726.737520, bitrate: N/A
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 640x480, 29.25 tbr, 1000k tbn, 1000k tbc
Output #0, video4linux2,v4l2, to '/dev/video1':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 640x480, q=2-31, 29.25 tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=   76 fps= 34 q=-1.0 Lsize=N/A time=00:00:02.52 bitrate=N/A speed=1.14x

No matter what -pix_fmt I pass, I always end up with yuv420p on the output.

I did several tests with both proper USB UVC webcams as well as DroidCam. The output pixel format never changes as expected. This is also not specific to requesting yuv422p as a pixel format. Also other formats are being ignored. Why is this happening? What am I missing?

Note: I have verified that ffmpeg is capable of the yuv422p pixel format (it is being listed when executing ffmpeg -pix_fmts).

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44

1 Answers1

2

You can't change pixel formats when using -c:v copy. Change to -c:v rawvideo.

Gyan
  • 85,394
  • 9
  • 169
  • 201