|
1 | | -## 🔎 Development Branch |
| 1 | +## 📸 Real-Time Embedded Linux Video Streaming System |
| 2 | +A real-time camera streaming system built on a Raspberry Pi that integrates a custom Linux kernel module, a multithreaded user-space capture pipeline, image processing, and MJPEG HTTP streaming. |
2 | 3 |
|
3 | | -This branch contains implementation-specific development work. |
| 4 | +This project demonstrates end-to-end system design across kernel space and user space. It combines Linux interfaces (V4L2, IOCTL, MMAP) with concurrent data pipelines and computer vision inference. |
4 | 5 |
|
5 | | -- `stream_detect` branch - Extends the base streaming pipeline with on-device object detection. |
| 6 | +#### 🌿 Branches |
| 7 | +- `main` - Stable, fully integrated version of the project |
| 8 | +- `stream` - Core camera capture and MJPEG streaming pipeline |
| 9 | +- `stream_detect` - Streaming pipeline with on-device object detection |
| 10 | +- `gh-pages` - Generated documentation hosted via github pages |
| 11 | + |
| 12 | +👉 Explore the generated docs: [Doxygen Documentation](https://hajjsalad.github.io/RaspberryPi-Cam-Streamer/html/index.html) |
| 13 | +👉 Explore how the documentation was structured and written: [Notes on Notion](https://www.notion.so/hajjsalad/Doxygen-Documentation-2dea741b5aab809989afdaf9d198430b). |
| 14 | +👉 Each key feature includes a link to in-depth implementation notes that describe how the module was designed and built. |
| 15 | +👉 This repository contains the backend implementation. The Android frontend is maintained in a separate repository: [Android Frontend repo](https://github.com/HajjSalad/RaspberryPi-Android-Video-Streaming) |
6 | 16 |
|
7 | | -👉 Full project documentation is maintaine in the `main` branch. |
| 17 | +#### 🗝️ System Components |
| 18 | +The backend is organized into five core components: |
| 19 | +- 🔌 **Kernel Device Driver** |
| 20 | + - Character device driver exposing camera control and LED status signaling via `ioctl` |
| 21 | + - Well-defined kernel ↔ user-space interface with minimal surface area |
| 22 | +- 📸 **V4L2 Camera Pipeline** |
| 23 | + - Camera configuration using V4L2 API, including format negotiation and stream parameters |
| 24 | + - Buffer allocation and zero-copy frame access via memory mapping I/O (MMAP) |
| 25 | + - Continuous frame capture with explicit buffer dequeue and re-queue operations |
| 26 | +- 🔄 **Multithreaded Producer-Consumer Pipeline** |
| 27 | + - Dedicated producer thread captures frames from the camera pipeline |
| 28 | + - Consumer thread streams encoded frames to connected HTTP clients |
| 29 | + - Lock-protected circular buffer ensure safe, low-latency data exchange between threads |
| 30 | +- 🖼️ **Image Processing Pipeline** |
| 31 | + - Multi-stage processing: YUYV422 → RGB24 color space conversion (BT.601) and JPEG compression (libjpeg) |
| 32 | + - Motion detection via frame differencing (SAD), |
| 33 | + - TensorFlow Lite object detection (MobileNet-SSD) |
| 34 | +- 📡 **MJPEG HTTP Streaming** |
| 35 | + - Lightweight TCP-based HTTP server bound to port 8080 |
| 36 | + - Handling client connections, routing requests via request manager |
| 37 | + - Delivering continuous MJPEG streams using multipart/x-mixed-replace protocol |
| 38 | + |
| 39 | +--- |
| 40 | +### 🔌 Custom Linux Kernel Module |
| 41 | +[Notes on Notion](https://www.notion.so/hajjsalad/Cam-Stream-Kernel-Module-2cca741b5aab80e1bddbe204e5e99eae) |
| 42 | +- Character device driver exposing camera control and LED status signaling via `ioctl` |
| 43 | +- Well-defined kernel ↔ user-space interface with minimal surface area |
| 44 | +- GPIO-driven LED indicators reflecting real-time camera streaming state |
| 45 | + |
| 46 | +`GPIO` · `IOCTL` · `Character device` · `Linux kernel` · `kernel ↔ user space interface` |
| 47 | + |
| 48 | +--- |
| 49 | +### 📸 V4L2-Based Camera Pipeline |
| 50 | +[Notes on Notion](https://www.notion.so/hajjsalad/V4L2-Streaming-Pipeline-2cca741b5aab80be8b30e62d9311b929) |
| 51 | + |
| 52 | +- Camera configuration using V4L2 API, including format negotiation and stream parameters |
| 53 | +- Buffer allocation and zero-copy frame access via memory mapping I/O (MMAP) |
| 54 | +- Continuous frame capture with explicit buffer dequeue and re-queue operations |
| 55 | + |
| 56 | +`V4L2` · `Camera drivers` · `MMAP` · `Buffer management` · `Video streaming` |
| 57 | + |
| 58 | +--- |
| 59 | +### 🔄 Multithreaded Producer-Consumer Architecture |
| 60 | +- Producer Thread |
| 61 | + - Continously capture frames from the camera using V4L2 |
| 62 | + - Converts raw frames to JPEG and pushes them into a circular buffer |
| 63 | + - Signals frame availability using a semaphore |
| 64 | +- Consumer Thread |
| 65 | + - Waits on the semaphore for available frames |
| 66 | + - Retrieves JPEG frames from the circular buffer |
| 67 | + - Streams JPEG frames to connected HTTP clients |
| 68 | + - Frees the memory of the processed frames |
| 69 | + |
| 70 | +This design allows for **producer thread** to run continously, while a new **consumer thread** is spawned per client. |
| 71 | + |
| 72 | +`Mutex` · `Semaphore` · `Circular buffers` · `Multithreading` · `Producer-consumer model` |
| 73 | + |
| 74 | +--- |
| 75 | +### 🖼️ Image Processing Pipeline |
| 76 | +[Notes on Notion](https://www.notion.so/hajjsalad/Object-Detection-2d2a741b5aab80ac958fc72ffb4de8a4) |
| 77 | +- Performs on-device inference using TensorFlow Lite on captured frames |
| 78 | +- Optimized for real-time edge deployment on the Raspberry Pi |
| 79 | + |
| 80 | +`Edge AI` · `Object Detection` · `Embedded ML` · `TensorFlow Lite` · `Real-time Inference`. |
| 81 | + |
| 82 | +--- |
| 83 | +### 📡 MJPEG HTTP Streaming |
| 84 | +[Notes on Notion](https://www.notion.so/hajjsalad/MJPEG-HTTP-Streaming-2cca741b5aab80d9ab6beddf8d86db00) |
| 85 | + |
| 86 | +- Lightweight HTTP server for serving video streams |
| 87 | +- Multipart MJPEG streaming compatible with web browsers and MJPEG clients |
| 88 | + |
| 89 | +`HTTP` · `MJPEG` · `Sockets` · `Lightweight server` · `Multipart streams` |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +### 🏗️ High Level Flow |
| 94 | + |
| 95 | + |
| 96 | +#### Program Flow Explanation |
| 97 | +``` |
| 98 | +main.c (Program Entry Point) |
| 99 | +├─> Initialize camera module (opens custom kernel module) |
| 100 | +├─> Start HTTP server for MJPEG streaming |
| 101 | +└─> Initialize threading pipeline |
| 102 | +
|
| 103 | +Producer Thread |
| 104 | +├─> Capture frames from the camera (YUYV format) |
| 105 | +├─> Convert YUYV → RGB |
| 106 | +├─> Optional: Perform object detection on RGB frames |
| 107 | +├─> Convert RGB → JPEG |
| 108 | +└─> Push JPEG frames into circular buffer |
| 109 | +
|
| 110 | +Consumer Thread |
| 111 | +├─> Retrieve JPEG frames from circular buffer |
| 112 | +└─> Stream frames over HTTP (MJPEG) |
| 113 | +
|
| 114 | +├─> Display stream in browser |
| 115 | +``` |
| 116 | +--- |
| 117 | +### ⚙️ Hardware |
| 118 | +- **Raspberry Pi 5** - primary embedded platform for kernel and user-space execution |
| 119 | +- **Logitech C270 USB webcam** - V4L2-compatible video capture device |
| 120 | +- **GPIO-connected RGB LED** - real-time system status indication |
| 121 | + - RED: idle state or error condition |
| 122 | + - GREEN: active camera streaming |
| 123 | + |
| 124 | +### 🧱 Build and Run |
| 125 | +- `make module`: Build the kernel module |
| 126 | +- `make user`: Build the user-space application |
| 127 | +- `make`: Build both the kernel module & user-space application |
| 128 | +- `sudo insmod kernel/cam_stream.ko`: Insert the kernel module |
| 129 | +- `sudo ./camera_client`: Start the camera streaming application |
| 130 | +- `http://<raspberry-pi-ip>/stream`: Open broswer and view the stream |
| 131 | + |
| 132 | +### 📂 Repository Structure |
| 133 | +``` |
| 134 | +📁 pi_live_stream/ |
| 135 | +│ |
| 136 | +├── docs/ # Doxygen-generated documentation |
| 137 | +│ |
| 138 | +├── kernel/ # Linux kernel module |
| 139 | +│ ├── cam_stream.c # Character device + ioctl implementation |
| 140 | +│ ├── cam_stream_ioctl.h # Shared ioctl interface (kernel ↔ user) |
| 141 | +│ └── Makefile # Kernel module build rules |
| 142 | +│ |
| 143 | +├── src/ # User-space application |
| 144 | +│ ├── camera/ # V4L2 camera capture & buffer management |
| 145 | +│ │ ├── camera.c |
| 146 | +│ │ └── camera.h |
| 147 | +│ │ |
| 148 | +│ ├── cb/ # Lock-protected circular buffer |
| 149 | +│ │ ├── circular_buffer.c |
| 150 | +│ │ └── circular_buffer.h |
| 151 | +│ │ |
| 152 | +│ ├── detection/ # Real-time object detection (TFLite) |
| 153 | +│ │ ├── detection.cpp |
| 154 | +│ │ ├── detection.h |
| 155 | +│ │ └── models/ |
| 156 | +│ │ └── detect.tflite |
| 157 | +│ │ |
| 158 | +│ ├── http/ # HTTP server + MJPEG streaming |
| 159 | +│ │ ├── http_server.c |
| 160 | +│ │ ├── http_server.h |
| 161 | +│ │ ├── mjpeg_stream.c |
| 162 | +│ │ └── mjpeg_stream.h |
| 163 | +│ │ |
| 164 | +│ ├── image/ # Image processing & encoding |
| 165 | +│ │ ├── image_encoder.c |
| 166 | +│ │ ├── image_encoder.h |
| 167 | +│ │ ├── image_processor.c |
| 168 | +│ │ └── image_processor.h |
| 169 | +│ │ |
| 170 | +│ └── main.c # Application entry point & thread orchestration |
| 171 | +│ |
| 172 | +├── README.md # Project overview & usage |
| 173 | +└── Makefile # Builds kernel module and user-space client |
| 174 | +``` |
0 commit comments