Skip to content

Commit ba3c09f

Browse files
committed
add stream counter
1 parent 5058cd9 commit ba3c09f

File tree

4 files changed

+55
-29
lines changed

4 files changed

+55
-29
lines changed

app_httpd.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ extern int streamPort;
5151
extern char httpURL[];
5252
extern char streamURL[];
5353
extern char default_index[];
54-
extern int8_t streamCount;
5554
extern unsigned long streamsServed;
5655
extern unsigned long imagesServed;
5756
extern int myRotation;
@@ -85,9 +84,6 @@ static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %
8584
httpd_handle_t stream_httpd = NULL;
8685
httpd_handle_t camera_httpd = NULL;
8786

88-
// Flag that can be set to kill all active streams
89-
bool streamKill;
90-
9187
#ifdef __cplusplus
9288
extern "C" {
9389
#endif
@@ -152,7 +148,7 @@ void serialDump() {
152148
int McuTc = (temprature_sens_read() - 32) / 1.8; // celsius
153149
int McuTf = temprature_sens_read(); // fahrenheit
154150
Serial.printf("System up: %" PRId64 ":%02i:%02i:%02i (d:h:m:s)\r\n", upDays, upHours, upMin, upSec);
155-
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);
156152
Serial.printf("CPU Freq: %i MHz, Xclk Freq: %i MHz\r\n", ESP.getCpuFreqMHz(), xclk);
157153
Serial.printf("MCU temperature : %i C, %i F (approximate)\r\n", McuTc, McuTf);
158154
Serial.printf("Heap: %i, free: %i, min free: %i, max block: %i\r\n", ESP.getHeapSize(), ESP.getFreeHeap(), ESP.getMinFreeHeap(), ESP.getMaxAllocHeap());
@@ -232,7 +228,10 @@ static esp_err_t stream_handler(httpd_req_t *req){
232228
printf("[stream_handler] could not get socket fd!\n");
233229
return ESP_FAIL;
234230
}
235-
cam_streamer_enqueue_client(cam_streamer, fd);
231+
232+
if(cam_streamer_enqueue_client(cam_streamer, fd))
233+
++streamsServed;
234+
236235
return ESP_OK;
237236
}
238237

@@ -307,7 +306,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){
307306
else if(!strcmp(variable, "autolamp") && (lampVal != -1)) {
308307
autoLamp = val;
309308
if (autoLamp) {
310-
if (streamCount > 0) setLamp(lampVal);
309+
if (cam_streamer_get_num_clients(cam_streamer) > 0) setLamp(lampVal);
311310
else setLamp(0);
312311
} else {
313312
setLamp(lampVal);
@@ -316,7 +315,7 @@ static esp_err_t cmd_handler(httpd_req_t *req){
316315
else if(!strcmp(variable, "lamp") && (lampVal != -1)) {
317316
lampVal = constrain(val,0,100);
318317
if (autoLamp) {
319-
if (streamCount > 0) setLamp(lampVal);
318+
if (cam_streamer_get_num_clients(cam_streamer) > 0) setLamp(lampVal);
320319
else setLamp(0);
321320
} else {
322321
setLamp(lampVal);
@@ -513,7 +512,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
513512
int McuTf = temprature_sens_read(); // fahrenheit
514513

515514
d+= sprintf(d,"Up: %" PRId64 ":%02i:%02i:%02i (d:h:m:s)<br>\n", upDays, upHours, upMin, upSec);
516-
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);
517516
d+= sprintf(d,"CPU Freq: %i MHz, Xclk Freq: %i MHz<br>\n", ESP.getCpuFreqMHz(), xclk);
518517
d+= sprintf(d,"<span title=\"NOTE: Internal temperature sensor readings can be innacurate on the ESP32-c1 chipset, and may vary significantly between devices!\">");
519518
d+= sprintf(d,"MCU temperature : %i &deg;C, %i &deg;F</span>\n<br>", McuTc, McuTf);
@@ -550,7 +549,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
550549
static esp_err_t stop_handler(httpd_req_t *req){
551550
flashLED(75);
552551
Serial.println("\r\nStream stop requested via Web");
553-
streamKill = true;
552+
cam_streamer_dequeue_all_clients(cam_streamer);
554553
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
555554
return httpd_resp_send(req, NULL, 0);
556555
}
@@ -794,7 +793,10 @@ void startCameraServer(int hPort, int sPort){
794793
httpd_register_uri_handler(stream_httpd, &info_uri);
795794
httpd_register_uri_handler(stream_httpd, &streamviewer_uri);
796795
cam_streamer=(cam_streamer_t *) malloc(sizeof(cam_streamer_t));
797-
cam_streamer_init(cam_streamer, stream_httpd, 3);
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);
798800
cam_streamer_start(cam_streamer);
799801
}
800802
httpd_register_uri_handler(stream_httpd, &favicon_16x16_uri);

cam_streamer.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,17 @@ static void cam_streamer_update_frame(cam_streamer_t *s) {
7878
#endif
7979
}
8080

81+
static void cam_streamer_decrement_num_clients(cam_streamer_t *s) {
82+
size_t num_clients=s->num_clients;
83+
while(num_clients>0 && !__atomic_compare_exchange_n(&s->num_clients, &num_clients, num_clients-1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED));
84+
#ifdef DEBUG_DEFAULT_ON
85+
printf("[cam_streamer] num_clients decremented\n");
86+
#endif
87+
}
88+
8189
void cam_streamer_task(void *p) {
8290
cam_streamer_t *s=(cam_streamer_t *) p;
8391

84-
uint8_t res;
8592
uint64_t last_time=0, current_time;
8693
int fd;
8794
unsigned int n_entries;
@@ -108,21 +115,26 @@ void cam_streamer_task(void *p) {
108115
printf("[cam_streamer] dequeued fd %d\n", fd);
109116
printf("[cam_streamer] sending part: \"%.*s\"\n", (int) s->part_len, s->part_buf);
110117
#endif
111-
if((res=is_send_error(httpd_socket_send(s->server, fd, s->part_buf, s->part_len, 0))))
118+
119+
if(is_send_error(httpd_socket_send(s->server, fd, s->part_buf, s->part_len, 0))) {
120+
cam_streamer_decrement_num_clients(s);
112121
continue;
122+
}
113123

114-
if((res|=is_send_error(httpd_socket_send(s->server, fd, s->buf->buf, s->buf->len, 0))))
124+
if(is_send_error(httpd_socket_send(s->server, fd, s->buf->buf, s->buf->len, 0))) {
125+
cam_streamer_decrement_num_clients(s);
115126
continue;
127+
}
116128

117-
if((res|=is_send_error(httpd_socket_send(s->server, fd, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY), 0))))
129+
if(is_send_error(httpd_socket_send(s->server, fd, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY), 0))) {
130+
cam_streamer_decrement_num_clients(s);
118131
continue;
132+
}
119133

120-
if(!res) {
134+
xQueueSend(s->clients, (void *) &fd, 10/portTICK_PERIOD_MS);
121135
#ifdef DEBUG_DEFAULT_ON
122-
printf("[cam_streamer] fd %d requeued\n", fd);
136+
printf("[cam_streamer] fd %d requeued\n", fd);
123137
#endif
124-
xQueueSend(s->clients, (void *) &fd, 10/portTICK_PERIOD_MS);
125-
}
126138
}
127139
}
128140
}
@@ -140,6 +152,15 @@ void cam_streamer_stop(cam_streamer_t *s) {
140152
vTaskDelete(s->task);
141153
}
142154

155+
size_t cam_streamer_get_num_clients(cam_streamer_t *s) {
156+
return s->num_clients;
157+
}
158+
159+
void cam_streamer_dequeue_all_clients(cam_streamer_t *s) {
160+
xQueueReset(s->clients);
161+
__atomic_exchange_n(&s->num_clients, 0, __ATOMIC_RELAXED);
162+
}
163+
143164
bool cam_streamer_enqueue_client(cam_streamer_t *s, int fd) {
144165
#ifdef DEBUG_DEFAULT_ON
145166
printf("sending stream headers:\n%s\nLength: %d\n", _STREAM_HEADERS, strlen(_STREAM_HEADERS));
@@ -170,6 +191,7 @@ bool cam_streamer_enqueue_client(cam_streamer_t *s, int fd) {
170191
#ifdef DEBUG_DEFAULT_ON
171192
printf("[cam_streamer] socket %d enqueued\n", fd);
172193
#endif
194+
__atomic_fetch_add(&s->num_clients, 1, __ATOMIC_RELAXED);
173195
vTaskResume(s->task);
174196
}
175197

cam_streamer.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,24 @@
1313

1414
#define CAM_STREAMER_MAX_CLIENTS 10
1515
typedef struct {
16-
QueueHandle_t clients;
17-
TaskHandle_t task;
18-
uint64_t last_updated;
19-
int64_t frame_delay;
20-
uint8_t buf_lock;
21-
camera_fb_t *buf;
22-
char part_buf[64];
23-
size_t part_len;
24-
httpd_handle_t server;
16+
QueueHandle_t clients;
17+
TaskHandle_t task;
18+
uint64_t last_updated;
19+
int64_t frame_delay;
20+
uint8_t buf_lock;
21+
camera_fb_t *buf;
22+
char part_buf[64];
23+
size_t part_len;
24+
httpd_handle_t server;
25+
size_t num_clients;
2526
} cam_streamer_t;
2627

2728
void cam_streamer_init(cam_streamer_t *s, httpd_handle_t server, uint16_t fps);
2829
void cam_streamer_task(void *p);
2930
void cam_streamer_start(cam_streamer_t *s);
3031
void cam_streamer_stop(cam_streamer_t *s);
3132
bool cam_streamer_enqueue_client(cam_streamer_t *s, int fd);
33+
size_t cam_streamer_get_num_clients(cam_streamer_t *s);
34+
void cam_streamer_dequeue_all_clients(cam_streamer_t *s);
3235

3336
#endif

esp32-cam-webserver.ino

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ char httpURL[64] = {"Undefined"};
136136
char streamURL[64] = {"Undefined"};
137137

138138
// Counters for info screens and debug
139-
int8_t streamCount = 0; // Number of currently active streams
140139
unsigned long streamsServed = 0; // Total completed streams
141140
unsigned long imagesServed = 0; // Total image requests
142141

0 commit comments

Comments
 (0)