Void Sentry
An AI-driven, real-time Sentry Turret platform leveraging asynchronous I/O and computer vision to deliver high-precision autonomous motion tracking on resource-constrained embedded hardware.
Loading...
Searching...
No Matches
stream_broadcaster.h
Go to the documentation of this file.
1
9#pragma once
10
11#include <array>
12#include <atomic>
13#include <cstddef>
14#include <cstdint>
15#include <optional>
16
17#include <esp_http_server.h>
18#include <freertos/FreeRTOS.h>
19#include <freertos/semphr.h>
20#include <freertos/task.h>
21
22#include "frame_slots.h"
23#include "frame_store.h"
24#include "viewer_set.h"
25
27{
28public:
30 bool start(httpd_handle_t server, FrameStore& store);
31
35 void stop();
36
38 static void on_session_closed(httpd_handle_t server, int sockfd);
39
40 uint32_t frames_sent() const { return sent_.load(); }
41
48 struct SendStats {
49 uint64_t total_us = 0;
50 uint32_t slow = 0;
51 uint32_t failed = 0;
52 uint32_t max_us = 0;
53 };
54 static constexpr uint32_t kSlowSendUs = 200000;
55
58
67 size_t viewer_count() const;
68
69private:
70 struct SendJob {
71 StreamBroadcaster* owner = nullptr;
72 int fd = -1;
73 size_t index = 0;
74 uint32_t generation = 0;
75 bool in_flight = false;
76 std::optional<frames::FrameLease> lease;
77 };
78
79 static esp_err_t ws_handler(httpd_req_t* req);
80 static esp_err_t pre_handshake(httpd_req_t* req); // ws_pre_handshake_cb: origin check, before the upgrade
81 static esp_err_t post_handshake(httpd_req_t* req); // registers the viewer once the session is a WebSocket
82 static void stream_task(void* arg);
83 static void send_job(void* arg);
84 void run();
85 void remove_viewer(int fd);
86 void wake_task(); // notify the stream task that a send finished
87
88 httpd_handle_t server_ = nullptr;
89 FrameStore* store_ = nullptr;
90 frames::ViewerSet viewers_;
91 std::array<SendJob, frames::kMaxViewers> jobs_{};
92 std::array<uint32_t, frames::kMaxViewers> generation_{}; // bumped per new viewer in a slot; guards viewers_
93 TaskHandle_t task_ = nullptr;
94 SemaphoreHandle_t mutex_ = nullptr; // guards viewers_, generation_ and jobs_[i].in_flight
95 std::atomic<uint32_t> sent_{0};
96 // Written only by send_job on the httpd task; read by take_send_stats() on loop().
97 std::atomic<uint64_t> send_us_total_{0};
98 std::atomic<uint32_t> send_slow_{0};
99 std::atomic<uint32_t> send_failed_{0};
100 std::atomic<uint32_t> send_us_max_{0};
101
102 static StreamBroadcaster* instance_; // close_fn has no user context
103};
Definition frame_store.h:30
Definition stream_broadcaster.h:27
void stop()
Stop the stream task and release all resources. Call BEFORE httpd_stop. Safe to call repeatedly.
Definition stream_broadcaster.cpp:58
bool start(httpd_handle_t server, FrameStore &store)
Register the /stream WebSocket endpoint and start the stream task (core 1, priority 4).
Definition stream_broadcaster.cpp:16
SendStats take_send_stats()
The send counters; resets max_us. For the stats line (one reader).
Definition stream_broadcaster.cpp:88
static void on_session_closed(httpd_handle_t server, int sockfd)
httpd close_fn: forget the viewer and close the socket (required when close_fn is set).
Definition stream_broadcaster.cpp:166
size_t viewer_count() const
Connected /stream viewers (0 to frames::kMaxViewers).
Definition stream_broadcaster.cpp:96
static constexpr uint32_t kSlowSendUs
200 ms: a visible hitch at 16 fps
Definition stream_broadcaster.h:54
Definition viewer_set.h:26
Slot bookkeeping for camera frames: who may write which slot, and RAII leases for readers.
Thread-safe home for camera frames: FrameSlots bookkeeping + fixed PSRAM buffers, allocated once.
How long frame sends block the httpd task (every /stream send runs on it, and so does /commands).
Definition stream_broadcaster.h:48
uint64_t total_us
time spent inside sends, since boot
Definition stream_broadcaster.h:49
uint32_t max_us
longest send since the previous call
Definition stream_broadcaster.h:52
uint32_t slow
sends that took at least kSlowSendUs
Definition stream_broadcaster.h:50
uint32_t failed
sends that returned an error (the viewer is dropped)
Definition stream_broadcaster.h:51
Which stream viewers should receive which frame (pure C++20, natively tested).