@@ -249,14 +249,14 @@ esp_err_t jpg_httpd_handler(httpd_req_t *req){
249
249
#define PART_BOUNDARY "123456789000000000000987654321"
250
250
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
251
251
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
252
- static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u \r\n\r\n";
252
+ static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %zu \r\n\r\n";
253
253
254
254
esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){
255
255
camera_fb_t * fb = NULL;
256
256
esp_err_t res = ESP_OK;
257
- size_t _jpg_buf_len ;
258
- uint8_t * _jpg_buf ;
259
- char * part_buf[64];
257
+ size_t jpg_buf_len = 0 ;
258
+ uint8_t * jpg_buf = NULL ;
259
+ char part_buf[64];
260
260
static int64_t last_frame = 0;
261
261
if(!last_frame) {
262
262
last_frame = esp_timer_get_time();
@@ -275,30 +275,36 @@ esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){
275
275
break;
276
276
}
277
277
if(fb->format != PIXFORMAT_JPEG){
278
- bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf , &_jpg_buf_len );
278
+ bool jpeg_converted = frame2jpg(fb, 80, &jpg_buf , &jpg_buf_len );
279
279
if(!jpeg_converted){
280
280
ESP_LOGE(TAG, "JPEG compression failed");
281
281
esp_camera_fb_return(fb);
282
282
res = ESP_FAIL;
283
+ break;
283
284
}
284
285
} else {
285
- _jpg_buf_len = fb->len;
286
- _jpg_buf = fb->buf;
286
+ jpg_buf_len = fb->len;
287
+ jpg_buf = fb->buf;
287
288
}
288
289
289
290
if(res == ESP_OK){
290
291
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
291
292
}
292
293
if(res == ESP_OK){
293
- size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
294
-
295
- res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
294
+ int hlen = snprintf(part_buf, sizeof(part_buf), _STREAM_PART, jpg_buf_len);
295
+ if(hlen < 0 || hlen >= sizeof(part_buf)){
296
+ ESP_LOGE(TAG, "Header truncated (%d bytes needed >= %zu buffer)",
297
+ hlen, sizeof(part_buf));
298
+ res = ESP_FAIL;
299
+ } else {
300
+ res = httpd_resp_send_chunk(req, part_buf, (size_t)hlen);
301
+ }
296
302
}
297
303
if(res == ESP_OK){
298
- res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len );
304
+ res = httpd_resp_send_chunk(req, (const char *)jpg_buf, jpg_buf_len );
299
305
}
300
306
if(fb->format != PIXFORMAT_JPEG){
301
- free(_jpg_buf );
307
+ free(jpg_buf );
302
308
}
303
309
esp_camera_fb_return(fb);
304
310
if(res != ESP_OK){
@@ -308,9 +314,10 @@ esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){
308
314
int64_t frame_time = fr_end - last_frame;
309
315
last_frame = fr_end;
310
316
frame_time /= 1000;
317
+ float fps = frame_time > 0 ? 1000.0f / (float)frame_time : 0.0f;
311
318
ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)",
312
- (uint32_t)(_jpg_buf_len /1024),
313
- (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time );
319
+ (uint32_t)(jpg_buf_len /1024),
320
+ (uint32_t)frame_time, fps );
314
321
}
315
322
316
323
last_frame = 0;
0 commit comments