28
28
#include " src/logo.h"
29
29
#include " storage.h"
30
30
31
+ extern " C" {
32
+ #include " cam_streamer.h"
33
+ }
31
34
// Functions from the main .ino
32
35
extern void flashLED (int flashtime);
33
36
extern void setLamp (int newVal);
@@ -48,7 +51,6 @@ extern int streamPort;
48
51
extern char httpURL[];
49
52
extern char streamURL[];
50
53
extern char default_index[];
51
- extern int8_t streamCount;
52
54
extern unsigned long streamsServed;
53
55
extern unsigned long imagesServed;
54
56
extern int myRotation;
@@ -67,6 +69,8 @@ extern char otaPassword[];
67
69
extern unsigned long xclk;
68
70
extern int sensorPID;
69
71
72
+ cam_streamer_t *cam_streamer;
73
+
70
74
typedef struct {
71
75
httpd_req_t *req;
72
76
size_t len;
@@ -80,9 +84,6 @@ static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %
80
84
httpd_handle_t stream_httpd = NULL ;
81
85
httpd_handle_t camera_httpd = NULL ;
82
86
83
- // Flag that can be set to kill all active streams
84
- bool streamKill;
85
-
86
87
#ifdef __cplusplus
87
88
extern " C" {
88
89
#endif
@@ -147,7 +148,7 @@ void serialDump() {
147
148
int McuTc = (temprature_sens_read () - 32 ) / 1.8 ; // celsius
148
149
int McuTf = temprature_sens_read (); // fahrenheit
149
150
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);
151
152
Serial.printf (" CPU Freq: %i MHz, Xclk Freq: %i MHz\r\n " , ESP.getCpuFreqMHz (), xclk);
152
153
Serial.printf (" MCU temperature : %i C, %i F (approximate)\r\n " , McuTc, McuTf);
153
154
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){
222
223
}
223
224
224
225
static 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;
321
236
}
322
237
323
238
static esp_err_t cmd_handler (httpd_req_t *req){
@@ -391,7 +306,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){
391
306
else if (!strcmp (variable, " autolamp" ) && (lampVal != -1 )) {
392
307
autoLamp = val;
393
308
if (autoLamp) {
394
- if (streamCount > 0 ) setLamp (lampVal);
309
+ if (cam_streamer_get_num_clients (cam_streamer) > 0 ) setLamp (lampVal);
395
310
else setLamp (0 );
396
311
} else {
397
312
setLamp (lampVal);
@@ -400,7 +315,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){
400
315
else if (!strcmp (variable, " lamp" ) && (lampVal != -1 )) {
401
316
lampVal = constrain (val,0 ,100 );
402
317
if (autoLamp) {
403
- if (streamCount > 0 ) setLamp (lampVal);
318
+ if (cam_streamer_get_num_clients (cam_streamer) > 0 ) setLamp (lampVal);
404
319
else setLamp (0 );
405
320
} else {
406
321
setLamp (lampVal);
@@ -597,7 +512,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
597
512
int McuTf = temprature_sens_read (); // fahrenheit
598
513
599
514
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);
601
516
d+= sprintf (d," CPU Freq: %i MHz, Xclk Freq: %i MHz<br>\n " , ESP.getCpuFreqMHz (), xclk);
602
517
d+= sprintf (d," <span title=\" NOTE: Internal temperature sensor readings can be innacurate on the ESP32-c1 chipset, and may vary significantly between devices!\" >" );
603
518
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){
634
549
static esp_err_t stop_handler (httpd_req_t *req){
635
550
flashLED (75 );
636
551
Serial.println (" \r\n Stream stop requested via Web" );
637
- streamKill = true ;
552
+ cam_streamer_dequeue_all_clients (cam_streamer) ;
638
553
httpd_resp_set_hdr (req, " Access-Control-Allow-Origin" , " *" );
639
554
return httpd_resp_send (req, NULL , 0 );
640
555
}
@@ -877,7 +792,13 @@ void startCameraServer(int hPort, int sPort){
877
792
httpd_register_uri_handler (stream_httpd, &stream_uri);
878
793
httpd_register_uri_handler (stream_httpd, &info_uri);
879
794
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
+ }
881
802
httpd_register_uri_handler (stream_httpd, &favicon_16x16_uri);
882
803
httpd_register_uri_handler (stream_httpd, &favicon_32x32_uri);
883
804
httpd_register_uri_handler (stream_httpd, &favicon_ico_uri);
0 commit comments