2828#include " src/logo.h"
2929#include " storage.h"
3030
31+ extern " C" {
32+ #include " cam_streamer.h"
33+ }
3134// Functions from the main .ino
3235extern void flashLED (int flashtime);
3336extern void setLamp (int newVal);
@@ -48,7 +51,6 @@ extern int streamPort;
4851extern char httpURL[];
4952extern char streamURL[];
5053extern char default_index[];
51- extern int8_t streamCount;
5254extern unsigned long streamsServed;
5355extern unsigned long imagesServed;
5456extern int myRotation;
@@ -67,6 +69,8 @@ extern char otaPassword[];
6769extern unsigned long xclk;
6870extern int sensorPID;
6971
72+ cam_streamer_t *cam_streamer;
73+
7074typedef struct {
7175 httpd_req_t *req;
7276 size_t len;
@@ -80,9 +84,6 @@ static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %
8084httpd_handle_t stream_httpd = NULL ;
8185httpd_handle_t camera_httpd = NULL ;
8286
83- // Flag that can be set to kill all active streams
84- bool streamKill;
85-
8687#ifdef __cplusplus
8788extern " C" {
8889#endif
@@ -147,7 +148,7 @@ void serialDump() {
147148 int McuTc = (temprature_sens_read () - 32 ) / 1.8 ; // celsius
148149 int McuTf = temprature_sens_read (); // fahrenheit
149150 Serial.printf (" System up: %" PRId64 " :%02i:%02i:%02i (d:h:m:s)\r\n " , upDays, upHours, upMin, upSec);
150- Serial.printf (" Active streams: %i , Previous streams: %lu, Images captured: %lu\r\n " , streamCount , streamsServed, imagesServed);
151+ Serial.printf (" Active streams: %lu , Previous streams: %lu, Images captured: %lu\r\n " , cam_streamer_get_num_clients (cam_streamer) , streamsServed, imagesServed);
151152 Serial.printf (" CPU Freq: %i MHz, Xclk Freq: %i MHz\r\n " , ESP.getCpuFreqMHz (), xclk);
152153 Serial.printf (" MCU temperature : %i C, %i F (approximate)\r\n " , McuTc, McuTf);
153154 Serial.printf (" Heap: %i, free: %i, min free: %i, max block: %i\r\n " , ESP.getHeapSize (), ESP.getFreeHeap (), ESP.getMinFreeHeap (), ESP.getMaxAllocHeap ());
@@ -222,102 +223,16 @@ static esp_err_t capture_handler(httpd_req_t *req){
222223}
223224
224225static esp_err_t stream_handler (httpd_req_t *req){
225- camera_fb_t * fb = NULL ;
226- esp_err_t res = ESP_OK;
227- size_t _jpg_buf_len = 0 ;
228- uint8_t * _jpg_buf = NULL ;
229- char * part_buf[64 ];
230-
231- streamKill = false ;
232-
233- Serial.println (" Stream requested" );
234- if (autoLamp && (lampVal != -1 )) setLamp (lampVal);
235- streamCount = 1 ; // at present we only have one stream handler, so values are 0 or 1..
236- flashLED (75 ); // double flash of status LED
237- delay (75 );
238- flashLED (75 );
239-
240- static int64_t last_frame = 0 ;
241- if (!last_frame) {
242- last_frame = esp_timer_get_time ();
243- }
244-
245- res = httpd_resp_set_type (req, _STREAM_CONTENT_TYPE);
246- if (res != ESP_OK){
247- streamCount = 0 ;
248- if (autoLamp && (lampVal != -1 )) setLamp (0 );
249- Serial.println (" STREAM: failed to set HTTP response type" );
250- return res;
251- }
252-
253- httpd_resp_set_hdr (req, " Access-Control-Allow-Origin" , " *" );
254-
255- if (res == ESP_OK){
256- res = httpd_resp_send_chunk (req, _STREAM_BOUNDARY, strlen (_STREAM_BOUNDARY));
257- }
258-
259- while (true ){
260- fb = esp_camera_fb_get ();
261- if (!fb) {
262- Serial.println (" STREAM: failed to acquire frame" );
263- res = ESP_FAIL;
264- } else {
265- if (fb->format != PIXFORMAT_JPEG){
266- Serial.println (" STREAM: Non-JPEG frame returned by camera module" );
267- res = ESP_FAIL;
268- } else {
269- _jpg_buf_len = fb->len ;
270- _jpg_buf = fb->buf ;
271- }
272- }
273- if (res == ESP_OK){
274- size_t hlen = snprintf ((char *)part_buf, 64 , _STREAM_PART, _jpg_buf_len);
275- res = httpd_resp_send_chunk (req, (const char *)part_buf, hlen);
276- }
277- if (res == ESP_OK){
278- res = httpd_resp_send_chunk (req, (const char *)_jpg_buf, _jpg_buf_len);
279- }
280- if (res == ESP_OK){
281- res = httpd_resp_send_chunk (req, _STREAM_BOUNDARY, strlen (_STREAM_BOUNDARY));
282- }
283- if (fb){
284- esp_camera_fb_return (fb);
285- fb = NULL ;
286- _jpg_buf = NULL ;
287- } else if (_jpg_buf){
288- free (_jpg_buf);
289- _jpg_buf = NULL ;
290- }
291- if (res != ESP_OK){
292- // This is the error exit point from the stream loop.
293- // We end the stream here only if a Hard failure has been encountered or the connection has been interrupted.
294- Serial.printf (" Stream failed, code = %i : %s\r\n " , res, esp_err_to_name (res));
295- break ;
296- }
297- if ((res != ESP_OK) || streamKill){
298- // We end the stream here when a kill is signalled.
299- Serial.printf (" Stream killed\r\n " );
300- break ;
301- }
302- int64_t frame_time = esp_timer_get_time () - last_frame;
303- frame_time /= 1000 ;
304- int32_t frame_delay = (minFrameTime > frame_time) ? minFrameTime - frame_time : 0 ;
305- delay (frame_delay);
306-
307- if (debugData) {
308- Serial.printf (" MJPG: %uB %ums, delay: %ums, framerate (%.1ffps)\r\n " ,
309- (uint32_t )(_jpg_buf_len),
310- (uint32_t )frame_time, frame_delay, 1000.0 / (uint32_t )(frame_time + frame_delay));
311- }
312- last_frame = esp_timer_get_time ();
313- }
314-
315- streamsServed++;
316- streamCount = 0 ;
317- if (autoLamp && (lampVal != -1 )) setLamp (0 );
318- Serial.println (" Stream ended" );
319- last_frame = 0 ;
320- return res;
226+ int fd=httpd_req_to_sockfd (req);
227+ if (fd==-1 ){
228+ printf (" [stream_handler] could not get socket fd!\n " );
229+ return ESP_FAIL;
230+ }
231+
232+ if (cam_streamer_enqueue_client (cam_streamer, fd))
233+ ++streamsServed;
234+
235+ return ESP_OK;
321236}
322237
323238static esp_err_t cmd_handler (httpd_req_t *req){
@@ -391,7 +306,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){
391306 else if (!strcmp (variable, " autolamp" ) && (lampVal != -1 )) {
392307 autoLamp = val;
393308 if (autoLamp) {
394- if (streamCount > 0 ) setLamp (lampVal);
309+ if (cam_streamer_get_num_clients (cam_streamer) > 0 ) setLamp (lampVal);
395310 else setLamp (0 );
396311 } else {
397312 setLamp (lampVal);
@@ -400,7 +315,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){
400315 else if (!strcmp (variable, " lamp" ) && (lampVal != -1 )) {
401316 lampVal = constrain (val,0 ,100 );
402317 if (autoLamp) {
403- if (streamCount > 0 ) setLamp (lampVal);
318+ if (cam_streamer_get_num_clients (cam_streamer) > 0 ) setLamp (lampVal);
404319 else setLamp (0 );
405320 } else {
406321 setLamp (lampVal);
@@ -597,7 +512,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
597512 int McuTf = temprature_sens_read (); // fahrenheit
598513
599514 d+= sprintf (d," Up: %" PRId64 " :%02i:%02i:%02i (d:h:m:s)<br>\n " , upDays, upHours, upMin, upSec);
600- d+= sprintf (d," Active streams: %i, Previous streams: %lu, Images captured: %lu<br>\n " , streamCount , streamsServed, imagesServed);
515+ d+= sprintf (d," Active streams: %i, Previous streams: %lu, Images captured: %lu<br>\n " , cam_streamer_get_num_clients (cam_streamer) , streamsServed, imagesServed);
601516 d+= sprintf (d," CPU Freq: %i MHz, Xclk Freq: %i MHz<br>\n " , ESP.getCpuFreqMHz (), xclk);
602517 d+= sprintf (d," <span title=\" NOTE: Internal temperature sensor readings can be innacurate on the ESP32-c1 chipset, and may vary significantly between devices!\" >" );
603518 d+= sprintf (d," MCU temperature : %i °C, %i °F</span>\n <br>" , McuTc, McuTf);
@@ -634,7 +549,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
634549static esp_err_t stop_handler (httpd_req_t *req){
635550 flashLED (75 );
636551 Serial.println (" \r\n Stream stop requested via Web" );
637- streamKill = true ;
552+ cam_streamer_dequeue_all_clients (cam_streamer) ;
638553 httpd_resp_set_hdr (req, " Access-Control-Allow-Origin" , " *" );
639554 return httpd_resp_send (req, NULL , 0 );
640555}
@@ -877,7 +792,13 @@ void startCameraServer(int hPort, int sPort){
877792 httpd_register_uri_handler (stream_httpd, &stream_uri);
878793 httpd_register_uri_handler (stream_httpd, &info_uri);
879794 httpd_register_uri_handler (stream_httpd, &streamviewer_uri);
880- }
795+ cam_streamer=(cam_streamer_t *) malloc (sizeof (cam_streamer_t ));
796+ #ifndef CAM_STREAMER_DESIRED_FPS
797+ #define CAM_STREAMER_DESIRED_FPS 2
798+ #endif
799+ cam_streamer_init (cam_streamer, stream_httpd, CAM_STREAMER_DESIRED_FPS);
800+ cam_streamer_start (cam_streamer);
801+ }
881802 httpd_register_uri_handler (stream_httpd, &favicon_16x16_uri);
882803 httpd_register_uri_handler (stream_httpd, &favicon_32x32_uri);
883804 httpd_register_uri_handler (stream_httpd, &favicon_ico_uri);
0 commit comments