Skip to content

Latest commit

 

History

History
127 lines (97 loc) · 4.3 KB

File metadata and controls

127 lines (97 loc) · 4.3 KB

FFmpeg-RaspberryPi

A small MJPEG streaming server for a USB (UVC) webcam, using the FFmpeg libraries directly for capture.

USB webcam → libavformat/libavdevice (v4l2 demux) → [libavcodec decode → libswscale → libavcodec encode, if --reencode] → HTTP multipart MJPEG → Browser
  • Pure C++17. Capture is done by linking directly against libavformat, libavcodec, libavdevice, libavutil and libswscale - there is no ffmpeg subprocess anymore, no argv-building, no pipe-parsing.
  • By default it asks the webcam for MJPEG directly (demuxer option input_format=mjpeg), so each packet libavformat hands back is already a complete JPEG frame - it's forwarded straight to the HTTP server with no decode/encode step, the same "zero conversion" philosophy as the original libcamera version. Cameras that don't support MJPEG natively can fall back to --reencode.
  • With --reencode, the camera is asked for raw YUYV422. Frames are decoded, converted with libswscale (YUYV422 → YUVJ422P), and encoded to MJPEG with libavcodec's own MJPEG encoder.
  • Multiple browsers can connect at once; each gets its own thread and the latest frame (identical HttpServer to the original project, unchanged).

Project layout

usb-camera-web/
├── CMakeLists.txt
├── main.cpp            # wires WebcamCapture -> HttpServer together
├── WebcamCapture.h/.cpp # demux/decode/scale/encode via libav* APIs
├── HttpServer.h/.cpp    # multipart/x-mixed-replace HTTP server (unchanged)
└── README.md

1. Install dependencies

This now needs the FFmpeg development headers/libraries (so pkg-config can find libavformat, libavcodec, libavdevice, libavutil and libswscale), not the ffmpeg command-line binary - ffmpeg itself doesn't need to be installed or on PATH anymore.

Raspberry Pi OS:

sudo apt update
sudo apt install -y build-essential cmake pkg-config v4l-utils \
    libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev

After installing, verify pkg-config can actually see the libraries before running cmake - this is the single most common setup problem:

pkg-config --modversion libavdevice

If that prints a version number, you're good. If it errors with Package 'libavdevice' ... not found, cmake will fail the same way at the pkg_check_modules step in CMakeLists.txt. That almost always means one of:

  • You installed the plain ffmpeg package but not the -dev/-devel headers (the runtime binary doesn't ship the .pc files pkg-config needs) - install the -dev/-devel packages above.
  • On Debian/Ubuntu, some minimal images split ffmpeg into universe/multiverse - make sure those repos are enabled (sudo add-apt-repository universe && sudo apt update) before installing.
  • You built/installed FFmpeg from source into a non-standard prefix (e.g. /usr/local) and PKG_CONFIG_PATH doesn't include it:
    export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
    then re-run cmake ...

Check that your webcam is visible and see what formats it supports:

v4l2-ctl --list-devices
v4l2-ctl -d /dev/video0 --list-formats-ext

Look for MJPG in that output - if your camera lists it, you can use the default (fast, no re-encode) mode below. If it only lists YUYV, use --reencode.

2. Build

mkdir build && cd build
cmake ..
make -j$(nproc)

3. Run

./ffmpeg-stream [device] [width] [height] [fps] [quality] [port] [--reencode]

All arguments are optional. Defaults: /dev/video0 640 480 15 5 8080, MJPEG passthrough (no re-encode).

./ffmpeg-stream                              # /dev/video0, 640x480@15fps, port 8080
./ffmpeg-stream /dev/video1 1280 720 10       # different device/resolution
./ffmpeg-stream /dev/video0 640 480 15 8 8080 --reencode
                                                # camera only does YUYV -> software encode, quality 8

Then open in a browser:

http://<host-ip>:8080/

/ serves a tiny HTML page with an <img> pointed at /stream, the raw multipart/x-mixed-replace MJPEG feed.

Stop the server with Ctrl+C - it tears down the libav contexts and closes all client connections cleanly.

License

This project is licensed under the GNU General Public License v3.0.