From b1b27409596247c210e8b2ecc7d0bb26faee1ed9 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 28 Nov 2023 22:29:12 -0500 Subject: [PATCH 1/3] =?UTF-8?q?feat(device):=20=F0=9F=8E=A5=20observer=20r?= =?UTF-8?q?tsp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device/observer_rtsp/.gitignore | 5 +++++ device/observer_rtsp/platformio.ini | 32 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 device/observer_rtsp/.gitignore create mode 100644 device/observer_rtsp/platformio.ini diff --git a/device/observer_rtsp/.gitignore b/device/observer_rtsp/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/device/observer_rtsp/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/device/observer_rtsp/platformio.ini b/device/observer_rtsp/platformio.ini new file mode 100644 index 0000000..603c696 --- /dev/null +++ b/device/observer_rtsp/platformio.ini @@ -0,0 +1,32 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +default_envs = esp-wrover-kit + +[env:esp-wrover-kit] +platform = espressif32 +board = esp-wrover-kit +framework = arduino +monitor_speed = 115200 +board_build.f_flash = 80000000L +board_build.flash_mode = qio +build_flags = -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue +lib_deps = + geeksville/Micro-RTSP@^0.1.6 + +[env:esp32-s3-devkitc-1] +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +monitor_speed = 115200 +lib_deps = + espressif/esp32-camera@^2.0.4 + geeksville/Micro-RTSP@^0.1.6 From 1498fc33b1c34cb9d08c961289a50c61d0e36f13 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 28 Nov 2023 22:29:31 -0500 Subject: [PATCH 2/3] =?UTF-8?q?feat(device):=20=F0=9F=8E=A5=20observer=20r?= =?UTF-8?q?tsp=20cam,=20wifi,=20pins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device/observer_rtsp/src/camera/cam.cpp | 84 ++++++ device/observer_rtsp/src/camera/cam.h | 24 ++ device/observer_rtsp/src/camera/cam_pins.h | 292 +++++++++++++++++++++ device/observer_rtsp/src/network/wifi.cpp | 30 +++ device/observer_rtsp/src/network/wifi.h | 16 ++ device/observer_rtsp/src/pins.h | 1 + 6 files changed, 447 insertions(+) create mode 100644 device/observer_rtsp/src/camera/cam.cpp create mode 100644 device/observer_rtsp/src/camera/cam.h create mode 100644 device/observer_rtsp/src/camera/cam_pins.h create mode 100644 device/observer_rtsp/src/network/wifi.cpp create mode 100644 device/observer_rtsp/src/network/wifi.h create mode 100644 device/observer_rtsp/src/pins.h diff --git a/device/observer_rtsp/src/camera/cam.cpp b/device/observer_rtsp/src/camera/cam.cpp new file mode 100644 index 0000000..824a9f8 --- /dev/null +++ b/device/observer_rtsp/src/camera/cam.cpp @@ -0,0 +1,84 @@ +#include // needed to include otherwise got 'Serial' not in scope errors +#include "esp_camera.h" +#include "camera/cam.h" +#include "camera/cam_pins.h" + +CamManager::CamManager() + : _cam_config{ + // --- pins + .pin_pwdn = PWDN_GPIO_NUM, + .pin_reset = RESET_GPIO_NUM, + .pin_xclk = XCLK_GPIO_NUM, + .pin_sscb_sda = SIOD_GPIO_NUM, + .pin_sscb_scl = SIOC_GPIO_NUM, + .pin_d7 = Y9_GPIO_NUM, + .pin_d6 = Y8_GPIO_NUM, + .pin_d5 = Y7_GPIO_NUM, + .pin_d4 = Y6_GPIO_NUM, + .pin_d3 = Y5_GPIO_NUM, + .pin_d2 = Y4_GPIO_NUM, + .pin_d1 = Y3_GPIO_NUM, + .pin_d0 = Y2_GPIO_NUM, + .pin_vsync = VSYNC_GPIO_NUM, + .pin_href = HREF_GPIO_NUM, + .pin_pclk = PCLK_GPIO_NUM, + // --- timers/clocks + .xclk_freq_hz = 20000000, // XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental) + .ledc_timer = LEDC_TIMER_0, + .ledc_channel = LEDC_CHANNEL_0, + // --- qualtiy settings + .pixel_format = PIXFORMAT_JPEG, // for streaming + .frame_size = FRAMESIZE_SXGA, // sizes: https://randomnerdtutorials.com/esp32-cam-ov2640-camera-settings/ + .jpeg_quality = 45, // 1 - 63 (lower numbers higher quality) + // --- buffer refrences + .fb_count = 1, // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. + .fb_location = CAMERA_FB_IN_PSRAM, // trying to fix an init issue (https://github.com/espressif/esp32-camera/issues/571#issuecomment-1726196189) + .grab_mode = CAMERA_GRAB_WHEN_EMPTY, + } +{ +} + +esp_err_t CamManager::initialize() +{ + Serial.println("[CamManager::initialize] esp_camera_init"); + // --- init + esp_err_t camera_init_result = esp_camera_init(&_cam_config); + if (camera_init_result != ESP_OK) + { + Serial.println("[CamManager::initialize] esp_camera_init FAILED"); + Serial.println(camera_init_result); + } + Serial.println("[CamManager::initialize] initial frame clearing"); + // --- clear first buffer: HACK: capture and throw away first frame. common issue with camera initialization/startup. the esp_camera_fb_return'ed a black frame or prior frame in loop below (did in setup, but after a crash doesn't seem to work): https://github.com/espressif/esp32-camera/issues/545#issuecomment-1600335819 + esp_camera_fb_return(esp_camera_fb_get()); + // --- return esp err/res + return camera_init_result; +} + +void CamManager::updateSettings() +{ + Serial.println("[CamManager::updateSettings] setting"); + sensor_t *s = esp_camera_sensor_get(); + s->set_brightness(s, 1); + s->set_saturation(s, 1); +} + +camera_fb_t *CamManager::capture() +{ + // --- capture + camera_fb_t *fb = esp_camera_fb_get(); + if (!fb) + Serial.println("[CamManager::capture] capture FAILED"); + else + Serial.println("[CamManager::capture] capture"); + // --- return + return fb; +} + +void CamManager::release(camera_fb_t *fb) +{ + if (fb) + esp_camera_fb_return(fb); + else + Serial.println("[CamManager::release] no frame buffer to release"); +} \ No newline at end of file diff --git a/device/observer_rtsp/src/camera/cam.h b/device/observer_rtsp/src/camera/cam.h new file mode 100644 index 0000000..174d928 --- /dev/null +++ b/device/observer_rtsp/src/camera/cam.h @@ -0,0 +1,24 @@ +// camera.h +#ifndef __cam_h__ +#define __cam_h__ + +#include "esp_camera.h" + +class CamManager +{ +public: + // --- constructor + CamManager(); + // --- setup/config + esp_err_t initialize(); + void updateSettings(); + // --- actions + camera_fb_t *capture(); + void release(camera_fb_t *fb); + +private: + camera_config_t _cam_config; + camera_model_t _cam_model = CAMERA_OV5640; +}; + +#endif // __cam_h__ \ No newline at end of file diff --git a/device/observer_rtsp/src/camera/cam_pins.h b/device/observer_rtsp/src/camera/cam_pins.h new file mode 100644 index 0000000..f63ff7e --- /dev/null +++ b/device/observer_rtsp/src/camera/cam_pins.h @@ -0,0 +1,292 @@ +// Change for w/e model you have (TODO: move this to an env var or read from ESP function if possible) +#define CAMERA_MODEL_WROVER_KIT + +// // TODO: trying to do a board w/o definition +// #define CAM_PIN_PWDN 39 +// #define CAM_PIN_RESET -1 // software reset will be performed +// #define CAM_PIN_XC 9 +// #define CAM_PIN_SDA 38 +// #define CAM_PIN_SCL 37 +// #define CAM_PIN_D9 18 // replaced PIN_D0 +// #define CAM_PIN_D8 17 // replaced PIN_D1 +// #define CAM_PIN_D7 4 +// #define CAM_PIN_D6 5 +// #define CAM_PIN_D5 6 +// #define CAM_PIN_D4 7 +// #define CAM_PIN_D3 15 +// #define CAM_PIN_D2 16 +// #define CAM_PIN_VS 45 +// #define CAM_PIN_HS 48 +// #define CAM_PIN_PC 47 + +#if defined(CAMERA_MODEL_WROVER_KIT) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 21 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 19 +#define Y4_GPIO_NUM 18 +#define Y3_GPIO_NUM 5 +#define Y2_GPIO_NUM 4 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_ESP_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#elif defined(CAMERA_MODEL_M5STACK_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_WIDE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_UNITCAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_AI_THINKER) +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 0 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 21 +#define Y4_GPIO_NUM 19 +#define Y3_GPIO_NUM 18 +#define Y2_GPIO_NUM 5 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL) +#define PWDN_GPIO_NUM 0 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD) +// The 18 pin header on the board has Y5 and Y3 swapped +#define USE_BOARD_HEADER 0 +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM 33 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 19 +#define Y7_GPIO_NUM 21 +#define Y6_GPIO_NUM 39 +#if USE_BOARD_HEADER +#define Y5_GPIO_NUM 13 +#else +#define Y5_GPIO_NUM 35 +#endif +#define Y4_GPIO_NUM 14 +#if USE_BOARD_HEADER +#define Y3_GPIO_NUM 35 +#else +#define Y3_GPIO_NUM 13 +#endif +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 40 +#define SIOD_GPIO_NUM 17 +#define SIOC_GPIO_NUM 18 + +#define Y9_GPIO_NUM 39 +#define Y8_GPIO_NUM 41 +#define Y7_GPIO_NUM 42 +#define Y6_GPIO_NUM 12 +#define Y5_GPIO_NUM 3 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 47 +#define Y2_GPIO_NUM 13 +#define VSYNC_GPIO_NUM 21 +#define HREF_GPIO_NUM 38 +#define PCLK_GPIO_NUM 11 + +#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD) +// The 18 pin header on the board has Y5 and Y3 swapped +#define USE_BOARD_HEADER 0 +#define PWDN_GPIO_NUM 1 +#define RESET_GPIO_NUM 2 +#define XCLK_GPIO_NUM 42 +#define SIOD_GPIO_NUM 41 +#define SIOC_GPIO_NUM 18 + +#define Y9_GPIO_NUM 16 +#define Y8_GPIO_NUM 39 +#define Y7_GPIO_NUM 40 +#define Y6_GPIO_NUM 15 +#if USE_BOARD_HEADER +#define Y5_GPIO_NUM 12 +#else +#define Y5_GPIO_NUM 13 +#endif +#define Y4_GPIO_NUM 5 +#if USE_BOARD_HEADER +#define Y3_GPIO_NUM 13 +#else +#define Y3_GPIO_NUM 12 +#endif +#define Y2_GPIO_NUM 14 +#define VSYNC_GPIO_NUM 38 +#define HREF_GPIO_NUM 4 +#define PCLK_GPIO_NUM 3 + +#elif defined(CAMERA_MODEL_ESP32S3_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 15 +#define SIOD_GPIO_NUM 4 +#define SIOC_GPIO_NUM 5 + +#define Y2_GPIO_NUM 11 +#define Y3_GPIO_NUM 9 +#define Y4_GPIO_NUM 8 +#define Y5_GPIO_NUM 10 +#define Y6_GPIO_NUM 12 +#define Y7_GPIO_NUM 18 +#define Y8_GPIO_NUM 17 +#define Y9_GPIO_NUM 16 + +#define VSYNC_GPIO_NUM 6 +#define HREF_GPIO_NUM 7 +#define PCLK_GPIO_NUM 13 + +#else +#error "Camera model not selected" +#endif \ No newline at end of file diff --git a/device/observer_rtsp/src/network/wifi.cpp b/device/observer_rtsp/src/network/wifi.cpp new file mode 100644 index 0000000..b57784b --- /dev/null +++ b/device/observer_rtsp/src/network/wifi.cpp @@ -0,0 +1,30 @@ +#include "wifi.h" + +WiFiManager::WiFiManager(const char *ssid, const char *password) +{ + this->ssid = ssid; + this->password = password; +} + +void WiFiManager::connect() +{ + Serial.print("[WiFiManager::connect] Connecting to WiFi..."); + WiFi.begin(ssid, password); + // --- attempt (<15 times) + int attempts = 0; + while (WiFi.status() != WL_CONNECTED && attempts < 15) + { + delay(500); + Serial.print("."); + attempts++; + } + Serial.println(); + // --- mention failure if hit 15 + if (WiFi.status() != WL_CONNECTED) + { + Serial.println("[WiFiManager::connect] Failed to connect to WiFi. Please check credentials and signal."); + return; // or handle the error differently + } + // --- mention connection! + Serial.println("[WiFiManager::connect] WiFi connected"); +} diff --git a/device/observer_rtsp/src/network/wifi.h b/device/observer_rtsp/src/network/wifi.h new file mode 100644 index 0000000..f0a8f3b --- /dev/null +++ b/device/observer_rtsp/src/network/wifi.h @@ -0,0 +1,16 @@ +#ifndef __wifi_h__ +#define __wifi_h__ + +#include + +class WiFiManager +{ +public: + WiFiManager(const char *ssid, const char *password); // Constructor + void connect(); // Method to connect to WiFi +private: + const char *ssid; + const char *password; +}; + +#endif \ No newline at end of file diff --git a/device/observer_rtsp/src/pins.h b/device/observer_rtsp/src/pins.h new file mode 100644 index 0000000..76ad96b --- /dev/null +++ b/device/observer_rtsp/src/pins.h @@ -0,0 +1 @@ +#define PIN_LED_BUILTIN 2 \ No newline at end of file From 74c1d75510f6804bec3f7d705b3dddd8509fc6b6 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 28 Nov 2023 22:30:06 -0500 Subject: [PATCH 3/3] =?UTF-8?q?feat(device):=20=F0=9F=8E=A5=20observer=20r?= =?UTF-8?q?tsp=20pull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device/observer_rtsp/src/main.cpp | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 device/observer_rtsp/src/main.cpp diff --git a/device/observer_rtsp/src/main.cpp b/device/observer_rtsp/src/main.cpp new file mode 100644 index 0000000..e0ede4b --- /dev/null +++ b/device/observer_rtsp/src/main.cpp @@ -0,0 +1,88 @@ +#include "OV2640.h" +#include +#include "esp_camera.h" +#include +#include +#include + +#include "CRtspSession.h" +#include "OV2640Streamer.h" + +#include "env.h" +#include "pins.h" +#include "camera/cam.h" +#include "network/wifi.h" + +// Camera +OV2640 cam; // needed to isolate for rtsp stream fns +CamManager camManager; // probably should just be funcs rather than class +// RTSP +WiFiClient rtspClient; +WiFiServer rtspServer(8554); +CStreamer *streamer = nullptr; +CRtspSession *session = nullptr; +// Wifi +WiFiManager myWiFiManager(ENV_WIFI_SSID, ENV_WIFI_PASSWORD); + +void setup() +{ + Serial.begin(115200); + Serial.setDebugOutput(true); + Serial.println(); + // --- stats + Serial.printf("[setup] CPU Freq: %d Mhz, %d core(s)\n", getCpuFrequencyMhz(), ESP.getChipCores()); + Serial.printf("[setup] Free heap: %d bytes\n", ESP.getFreeHeap()); + Serial.printf("[setup] Free PSRAM: %d bytes\n", ESP.getFreePsram()); + Serial.printf("[setup] SDK version: %s\n", ESP.getSdkVersion()); + Serial.printf("[setup] ESP Device ID: %d\n", ESP.getEfuseMac()); + // --- wifi + myWiFiManager.connect(); + // --- camera + esp_err_t camera_init_result = camManager.initialize(); + if (camera_init_result == ESP_OK) + camManager.updateSettings(); + // --- rtsp + rtspServer.begin(); + Serial.println("[setup] done"); +} + +void loop() +{ + // RTSP + uint32_t msecPerFrame = 500; + static uint32_t lastimageAt = millis(); + // --- if connection + if (session) + { + session->handleRequests(0); + // instead of timeout (which would be blocking), send when enough milliseconds have passed + uint32_t now = millis(); + if (now > lastimageAt + msecPerFrame || now < lastimageAt) + { + // Serial.printf("session->m_streaming: %d\n", session->m_streaming); + session->broadcastCurrentFrame(now); + lastimageAt = now; + // check if we are overrunning our max frame rate + now = millis(); + if (now > lastimageAt + msecPerFrame) + Serial.printf("[loop] warning exceeding max frame rate of %d ms\n", now - lastimageAt); + } + if (session->m_stopped) + { + delete session; + delete streamer; + session = NULL; + streamer = NULL; + } + } + else + { + rtspClient = rtspServer.accept(); + if (rtspClient) + { + Serial.println("[loop] new streamer + rtspClient"); + streamer = new OV2640Streamer(&rtspClient, cam); // our streamer for UDP/TCP based RTP transport + session = new CRtspSession(&rtspClient, streamer); // our threads RTSP session and state + } + } +}