diff --git a/components/StateManager/StateManager/StateManager.cpp b/components/StateManager/StateManager/StateManager.cpp index 7d2196a..a7567b5 100644 --- a/components/StateManager/StateManager/StateManager.cpp +++ b/components/StateManager/StateManager/StateManager.cpp @@ -63,9 +63,9 @@ void StateManager::HandleUpdateState() ledStreamState = LEDStates_e::LedStateStreaming; 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); } break; @@ -87,6 +87,11 @@ CameraState_e StateManager::GetCameraState() return this->camera_state; } +QueueHandle_t StateManager::GetEventQueue() const +{ + return this->eventQueue; +} + void HandleStateManagerTask(void *pvParameters) { auto *stateManager = static_cast(pvParameters); diff --git a/components/StateManager/StateManager/StateManager.hpp b/components/StateManager/StateManager/StateManager.hpp index 4541e2f..ed49e60 100644 --- a/components/StateManager/StateManager/StateManager.hpp +++ b/components/StateManager/StateManager/StateManager.hpp @@ -76,6 +76,7 @@ class StateManager void HandleUpdateState(); WiFiState_e GetWifiState(); CameraState_e GetCameraState(); + QueueHandle_t GetEventQueue() const; private: QueueHandle_t eventQueue; @@ -87,6 +88,15 @@ class StateManager 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); #endif // STATEMANAGER_HPP diff --git a/components/StreamServer/StreamServer/StreamServer.cpp b/components/StreamServer/StreamServer/StreamServer.cpp index de448e7..42fcfa4 100644 --- a/components/StreamServer/StreamServer/StreamServer.cpp +++ b/components/StreamServer/StreamServer/StreamServer.cpp @@ -26,6 +26,11 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) if (!last_frame) last_frame = esp_timer_get_time(); + // Pull event queue from user_ctx to send STREAM on/off notifications + auto *stateManager = static_cast(req->user_ctx); + QueueHandle_t eventQueue = stateManager ? stateManager->GetEventQueue() : nullptr; + bool stream_on_sent = false; + response = httpd_resp_set_type(req, STREAM_CONTENT_TYPE); if (response != ESP_OK) return response; @@ -33,6 +38,9 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_set_hdr(req, "X-Framerate", "60"); + if (SendStreamEvent(eventQueue, StreamState_e::Stream_ON)) + stream_on_sent = true; + while (true) { fb = esp_camera_fb_get(); @@ -86,6 +94,10 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) } } last_frame = 0; + + if (stream_on_sent) + SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); + return response; } @@ -110,7 +122,7 @@ esp_err_t StreamServer::startStreamServer() .uri = "/", .method = HTTP_GET, .handler = &StreamHelpers::stream, - .user_ctx = nullptr, + .user_ctx = this->stateManager, }; httpd_uri_t logs_ws = { @@ -138,6 +150,10 @@ esp_err_t StreamServer::startStreamServer() 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); return ESP_OK; diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index 5a55416..2967057 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -67,8 +67,7 @@ static esp_err_t UVCStreamHelpers::camera_start_cb(uvc_format_t format, int widt cameraHandler->setCameraResolution(frame_size); - constexpr SystemEvent event = {EventSource::STREAM, StreamState_e::Stream_ON}; - xQueueSend(eventQueue, &event, 10); + SendStreamEvent(eventQueue, StreamState_e::Stream_ON); return ESP_OK; } @@ -82,8 +81,7 @@ static void UVCStreamHelpers::camera_stop_cb(void *cb_ctx) s_fb.cam_fb_p = nullptr; } - constexpr SystemEvent event = {EventSource::STREAM, StreamState_e::Stream_OFF}; - xQueueSend(eventQueue, &event, 10); + SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); } 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"); + // Initial state is OFF + SendStreamEvent(eventQueue, StreamState_e::Stream_OFF); + return ESP_OK; }