Merge pull request #27 from m-RNA/update-stream_state-events

Unify stream state events across HTTP and UVC for LED feedback
This commit is contained in:
Lorow
2025-12-31 20:18:14 +01:00
committed by GitHub
4 changed files with 39 additions and 7 deletions

View File

@@ -63,9 +63,9 @@ void StateManager::HandleUpdateState()
ledStreamState = LEDStates_e::LedStateStreaming; ledStreamState = LEDStates_e::LedStateStreaming;
xQueueSend(this->ledStateQueue, &ledStreamState, 10); xQueueSend(this->ledStateQueue, &ledStreamState, 10);
} }
if (this->stream_state == StreamState_e::Stream_ON) else if (this->stream_state == StreamState_e::Stream_OFF)
{ {
ledStreamState = LEDStates_e::LedStateStreaming; ledStreamState = LEDStates_e::LedStateStoppedStreaming;
xQueueSend(this->ledStateQueue, &ledStreamState, 10); xQueueSend(this->ledStateQueue, &ledStreamState, 10);
} }
break; break;
@@ -87,6 +87,11 @@ CameraState_e StateManager::GetCameraState()
return this->camera_state; return this->camera_state;
} }
QueueHandle_t StateManager::GetEventQueue() const
{
return this->eventQueue;
}
void HandleStateManagerTask(void *pvParameters) void HandleStateManagerTask(void *pvParameters)
{ {
auto *stateManager = static_cast<StateManager *>(pvParameters); auto *stateManager = static_cast<StateManager *>(pvParameters);

View File

@@ -76,6 +76,7 @@ public:
void HandleUpdateState(); void HandleUpdateState();
WiFiState_e GetWifiState(); WiFiState_e GetWifiState();
CameraState_e GetCameraState(); CameraState_e GetCameraState();
QueueHandle_t GetEventQueue() const;
private: private:
QueueHandle_t eventQueue; QueueHandle_t eventQueue;
@@ -87,6 +88,15 @@ private:
StreamState_e stream_state; StreamState_e stream_state;
}; };
// Lightweight helper to publish stream state changes to the shared event queue.
static inline bool SendStreamEvent(QueueHandle_t queue, StreamState_e state)
{
if (!queue)
return false;
SystemEvent evt{EventSource::STREAM, state};
return xQueueSend(queue, &evt, 0) == pdTRUE;
}
void HandleStateManagerTask(void *pvParameters); void HandleStateManagerTask(void *pvParameters);
#endif // STATEMANAGER_HPP #endif // STATEMANAGER_HPP

View File

@@ -25,6 +25,11 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req)
if (!last_frame) if (!last_frame)
last_frame = esp_timer_get_time(); last_frame = esp_timer_get_time();
// Pull event queue from user_ctx to send STREAM on/off notifications
auto *stateManager = static_cast<StateManager *>(req->user_ctx);
QueueHandle_t eventQueue = stateManager ? stateManager->GetEventQueue() : nullptr;
bool stream_on_sent = false;
response = httpd_resp_set_type(req, STREAM_CONTENT_TYPE); response = httpd_resp_set_type(req, STREAM_CONTENT_TYPE);
if (response != ESP_OK) if (response != ESP_OK)
return response; return response;
@@ -32,6 +37,9 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req)
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_set_hdr(req, "X-Framerate", "60"); httpd_resp_set_hdr(req, "X-Framerate", "60");
if (SendStreamEvent(eventQueue, StreamState_e::Stream_ON))
stream_on_sent = true;
while (true) while (true)
{ {
fb = esp_camera_fb_get(); fb = esp_camera_fb_get();
@@ -100,6 +108,10 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req)
} }
} }
last_frame = 0; last_frame = 0;
if (stream_on_sent)
SendStreamEvent(eventQueue, StreamState_e::Stream_OFF);
return response; return response;
} }
@@ -124,7 +136,7 @@ esp_err_t StreamServer::startStreamServer()
.uri = "/", .uri = "/",
.method = HTTP_GET, .method = HTTP_GET,
.handler = &StreamHelpers::stream, .handler = &StreamHelpers::stream,
.user_ctx = nullptr, .user_ctx = this->stateManager,
}; };
httpd_uri_t logs_ws = { httpd_uri_t logs_ws = {
@@ -152,6 +164,10 @@ esp_err_t StreamServer::startStreamServer()
httpd_register_uri_handler(camera_stream, &stream_page); httpd_register_uri_handler(camera_stream, &stream_page);
// Initial state is OFF
if (this->stateManager)
SendStreamEvent(this->stateManager->GetEventQueue(), StreamState_e::Stream_OFF);
ESP_LOGI(STREAM_SERVER_TAG, "Stream server started on port %d", STREAM_SERVER_PORT); ESP_LOGI(STREAM_SERVER_TAG, "Stream server started on port %d", STREAM_SERVER_PORT);
return ESP_OK; return ESP_OK;

View File

@@ -67,8 +67,7 @@ static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int widt
cameraHandler->setCameraResolution(frame_size); cameraHandler->setCameraResolution(frame_size);
constexpr SystemEvent event = {EventSource::STREAM, StreamState_e::Stream_ON}; SendStreamEvent(eventQueue, StreamState_e::Stream_ON);
xQueueSend(eventQueue, &event, 10);
return ESP_OK; return ESP_OK;
} }
@@ -82,8 +81,7 @@ static void UVCStreamHelpers::camera_stop_cb(void *cb_ctx)
s_fb.cam_fb_p = nullptr; s_fb.cam_fb_p = nullptr;
} }
constexpr SystemEvent event = {EventSource::STREAM, StreamState_e::Stream_OFF}; SendStreamEvent(eventQueue, StreamState_e::Stream_OFF);
xQueueSend(eventQueue, &event, 10);
} }
static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx) static uvc_fb_t *UVCStreamHelpers::camera_fb_get_cb(void *cb_ctx)
@@ -205,6 +203,9 @@ esp_err_t UVCStreamManager::setup()
} }
ESP_LOGI(UVC_STREAM_TAG, "Initialized UVC Device"); ESP_LOGI(UVC_STREAM_TAG, "Initialized UVC Device");
// Initial state is OFF
SendStreamEvent(eventQueue, StreamState_e::Stream_OFF);
return ESP_OK; return ESP_OK;
} }