mirror of
https://github.com/arendst/Tasmota.git
synced 2026-07-27 20:05:46 +00:00
Add webcam support for resolutions 16 to 24
- Changes disable camera (resolution) from option 15 to -1
This commit is contained in:
@@ -351,7 +351,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t contrast : 3;
|
||||
uint32_t brightness : 3;
|
||||
uint32_t saturation : 3;
|
||||
uint32_t resolution : 4;
|
||||
uint32_t resolution : 4; // Resolution bits0..4
|
||||
};
|
||||
} WebCamCfg;
|
||||
|
||||
@@ -365,7 +365,7 @@ typedef union {
|
||||
uint32_t agc_gain: 5;
|
||||
uint32_t special_effect : 3;
|
||||
uint32_t auth : 1;
|
||||
uint32_t spare29 : 1;
|
||||
uint32_t resolution : 1; // Resolution bit5
|
||||
uint32_t spare30 : 1;
|
||||
uint32_t upgraded : 1;
|
||||
};
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
13 = FRAMESIZE_HD, // 1280x720
|
||||
14 = FRAMESIZE_SXGA, // 1280x1024
|
||||
15 = FRAMESIZE_UXGA, // 1600x1200
|
||||
// 3MP Sensors above this no yet supported with this driver
|
||||
// 3MP Sensors
|
||||
16 = FRAMESIZE_FHD, // 1920x1080
|
||||
17 = FRAMESIZE_P_HD, // 720x1280
|
||||
18 = FRAMESIZE_P_3MP, // 864x1536
|
||||
@@ -217,6 +217,15 @@ struct {
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
int32_t WcResolutionSetting(int32_t resolution = -1);
|
||||
int32_t WcResolutionSetting(int32_t resolution) {
|
||||
if (resolution > -1) {
|
||||
Settings->webcam_config.resolution = resolution & 0xF;
|
||||
Settings->webcam_config2.resolution = resolution >> 4 & 0x1;
|
||||
}
|
||||
return Settings->webcam_config2.resolution << 4 | Settings->webcam_config.resolution;
|
||||
}
|
||||
|
||||
void WcInterrupt(uint32_t state) {
|
||||
TasAutoMutex localmutex(&WebcamMutex, "WcInterrupt");
|
||||
// Stop camera ISR if active to fix TG1WDT_SYS_RESET
|
||||
@@ -372,7 +381,7 @@ uint32_t WcSetup(int32_t fsiz) {
|
||||
TasAutoMutex localmutex(&WebcamMutex, "WcSetup");
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: WcSetup"));
|
||||
if (fsiz >= FRAMESIZE_FHD) { fsiz = FRAMESIZE_FHD - 1; }
|
||||
if (fsiz >= FRAMESIZE_INVALID) { fsiz = FRAMESIZE_INVALID - 1; }
|
||||
|
||||
int stream_active = Wc.stream_active;
|
||||
Wc.stream_active = 0;
|
||||
@@ -1084,7 +1093,7 @@ void WcInterruptControl() {
|
||||
|
||||
WcSetStreamserver(Settings->webcam_config.stream);
|
||||
if(Wc.up == 0) {
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1167,7 +1176,7 @@ void WcShowStream(void) {
|
||||
void WcInit(void) {
|
||||
if (!Settings->webcam_config.data) {
|
||||
Settings->webcam_config.stream = 1;
|
||||
Settings->webcam_config.resolution = FRAMESIZE_QVGA;
|
||||
WcResolutionSetting(FRAMESIZE_QVGA);
|
||||
WcSetDefaults(0);
|
||||
}
|
||||
// previous webcam driver had only a small subset of possible config vars
|
||||
@@ -1266,7 +1275,7 @@ void CmndWebcam(void) {
|
||||
",\"" D_CMND_RTSP "\":%d"
|
||||
#endif // ENABLE_RTSPSERVER
|
||||
"}}"),
|
||||
Settings->webcam_config.stream, Settings->webcam_config.resolution, Settings->webcam_config.mirror,
|
||||
Settings->webcam_config.stream, WcResolutionSetting(), Settings->webcam_config.mirror,
|
||||
Settings->webcam_config.flip,
|
||||
Settings->webcam_config.saturation -2, Settings->webcam_config.brightness -2, Settings->webcam_config.contrast -2,
|
||||
Settings->webcam_config2.special_effect, Settings->webcam_config.awb, Settings->webcam_config2.wb_mode,
|
||||
@@ -1294,11 +1303,11 @@ void CmndWebcamStream(void) {
|
||||
}
|
||||
|
||||
void CmndWebcamResolution(void) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < FRAMESIZE_FHD)) {
|
||||
Settings->webcam_config.resolution = XdrvMailbox.payload;
|
||||
WcSetOptions(0, Settings->webcam_config.resolution);
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < FRAMESIZE_INVALID)) {
|
||||
WcResolutionSetting(XdrvMailbox.payload);
|
||||
WcSetOptions(0, WcResolutionSetting());
|
||||
}
|
||||
ResponseCmndNumber(Settings->webcam_config.resolution);
|
||||
ResponseCmndNumber(WcResolutionSetting());
|
||||
}
|
||||
|
||||
void CmndWebcamMirror(void) {
|
||||
@@ -1501,7 +1510,7 @@ void CmndWebcamClock(void){
|
||||
}
|
||||
|
||||
void CmndWebcamInit(void) {
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
WcInterruptControl();
|
||||
ResponseCmndDone();
|
||||
}
|
||||
@@ -1594,7 +1603,7 @@ bool Xdrv81(uint32_t function) {
|
||||
WcInit();
|
||||
break;
|
||||
case FUNC_INIT:
|
||||
if(Wc.up == 0) WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
if(Wc.up == 0) WcSetup((int32_t)WcResolutionSetting());
|
||||
break;
|
||||
case FUNC_ACTIVE:
|
||||
result = true;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
* Supported commands:
|
||||
* WcInterrupt = Control streaming, 0 = stop, 1 = start
|
||||
* WcResolution = Set resolution (max framerates at wcclock=20)
|
||||
**** Pre v14.4.0 ****
|
||||
* FPS quoted is (max, withonewebclient) at wcclock=20 on AIThinker esp32cam equivalent
|
||||
* FPS is mostly limited by sending data to webclients & rtsp, not by the camera.
|
||||
0 = FRAMESIZE_96X96, // 96x96 (50fps, ~48fps) - at wcclock=30 (75, ~53)
|
||||
@@ -65,6 +66,38 @@
|
||||
21 = FRAMESIZE_QSXGA, // 2560x1920
|
||||
22 = FRAMESIZE_INVALID
|
||||
|
||||
**** Post v14.4.0 ****
|
||||
0 = FRAMESIZE_96X96, // 96x96
|
||||
1 = FRAMESIZE_QQVGA, // 160x120
|
||||
2 = FRAMESIZE_128X128, // 128x128
|
||||
3 = FRAMESIZE_QCIF, // 176x144
|
||||
4 = FRAMESIZE_HQVGA, // 240x176
|
||||
5 = FRAMESIZE_240X240, // 240x240
|
||||
6 = FRAMESIZE_QVGA, // 320x240
|
||||
7 = FRAMESIZE_320X320, // 320x320 (Known not to work. See https://github.com/espressif/arduino-esp32/pull/10814)
|
||||
8 = FRAMESIZE_CIF, // 400x296
|
||||
9 = FRAMESIZE_HVGA, // 480x320
|
||||
10 = FRAMESIZE_VGA, // 640x480
|
||||
11 = FRAMESIZE_SVGA, // 800x600
|
||||
12 = FRAMESIZE_XGA, // 1024x768
|
||||
13 = FRAMESIZE_HD, // 1280x720
|
||||
14 = FRAMESIZE_SXGA, // 1280x1024
|
||||
15 = FRAMESIZE_UXGA, // 1600x1200
|
||||
// 3MP Sensors
|
||||
16 = FRAMESIZE_FHD, // 1920x1080
|
||||
17 = FRAMESIZE_P_HD, // 720x1280
|
||||
18 = FRAMESIZE_P_3MP, // 864x1536
|
||||
19 = FRAMESIZE_QXGA, // 2048x1536
|
||||
// 5MP Sensors
|
||||
20 = FRAMESIZE_QHD, // 2560x1440
|
||||
21 = FRAMESIZE_WQXGA, // 2560x1600
|
||||
22 = FRAMESIZE_P_FHD, // 1080x1920
|
||||
23 = FRAMESIZE_QSXGA, // 2560x1920
|
||||
24 = FRAMESIZE_5MP, // 2592x1944
|
||||
25 = FRAMESIZE_INVALID
|
||||
// This driver
|
||||
31 = CAMERA DISABLED (from wcresolution -1)
|
||||
|
||||
Framerate: I found that achievable streamed framerate is VERY dependent on wifi.
|
||||
e.g. latest BT router, but with android screensharing with TV, and framerate for resolution 0 was scatty between 20 and 40fps!!!!
|
||||
As soon as the screenshare ended, back to 53fps at 30mhz clock.
|
||||
@@ -489,6 +522,22 @@ struct {
|
||||
|
||||
#define WC_USE_FAST_MEM 0x10
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
int32_t WcResolutionSetting(int32_t resolution = -2);
|
||||
int32_t WcResolutionSetting(int32_t resolution) {
|
||||
if (resolution > -2) {
|
||||
if (-1 == resolution) { resolution = 31; }
|
||||
Settings->webcam_config.resolution = resolution & 0xF;
|
||||
Settings->webcam_config2.resolution = resolution >> 4 & 0x1;
|
||||
}
|
||||
resolution = Settings->webcam_config2.resolution << 4 | Settings->webcam_config.resolution;
|
||||
if (31 == resolution) { resolution = -1; } // Disable Camera
|
||||
return resolution;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
bool pic_alloc(struct PICSTORE *ps, int width, int height, int jpegsize, int format, int allocstyle){
|
||||
int len = 0;
|
||||
bool res = false;
|
||||
@@ -931,8 +980,8 @@ uint32_t WcSetup(int32_t fsiz) {
|
||||
#ifdef WEBCAM_DEV_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: WcSetup"));
|
||||
#endif
|
||||
// if 15, make it -1, so disableing
|
||||
if (fsiz >= FRAMESIZE_FHD) { fsiz = -1; }
|
||||
// if FRAMESIZE_INVALID, make it -1, so disableing
|
||||
if (fsiz >= FRAMESIZE_INVALID) { fsiz = -1; }
|
||||
|
||||
if (fsiz < 0) {
|
||||
if (Wc.up){
|
||||
@@ -1179,7 +1228,7 @@ int32_t WcSetOptions(uint32_t sel, int32_t value) {
|
||||
// pixelformat - native formats + 1, 0->jpeg
|
||||
if (value >= 0) { Wc.camPixelFormat = value; }
|
||||
if (Wc.up){
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
}
|
||||
return value;
|
||||
break;
|
||||
@@ -2275,7 +2324,7 @@ void WcInit(void) {
|
||||
if (!Settings->webcam_config.data) {
|
||||
// set defaults...
|
||||
Settings->webcam_config.stream = 1;
|
||||
Settings->webcam_config.resolution = FRAMESIZE_QVGA;
|
||||
WcResolutionSetting(FRAMESIZE_QVGA);
|
||||
WcSetDefaults(0);
|
||||
}
|
||||
// previous webcam driver had only a small subset of possible config vars
|
||||
@@ -2421,7 +2470,7 @@ void CmndWebcam(void) {
|
||||
",\"" D_CMND_RTSP "\":%d"
|
||||
#endif // ENABLE_RTSPSERVER
|
||||
"}}"),
|
||||
Settings->webcam_config.stream, Settings->webcam_config.resolution, Settings->webcam_config.mirror,
|
||||
Settings->webcam_config.stream, WcResolutionSetting(), Settings->webcam_config.mirror,
|
||||
Settings->webcam_config.flip,
|
||||
Settings->webcam_config.saturation -2, Settings->webcam_config.brightness -2, Settings->webcam_config.contrast -2,
|
||||
Settings->webcam_config2.special_effect, Settings->webcam_config.awb, Settings->webcam_config2.wb_mode,
|
||||
@@ -2649,20 +2698,20 @@ void CmndWebcamStream(void) {
|
||||
}
|
||||
|
||||
void CmndWebcamResolution(void) {
|
||||
if ((XdrvMailbox.payload >= -1) && (XdrvMailbox.payload < FRAMESIZE_FHD)) {
|
||||
if ((XdrvMailbox.payload >= -1) && (XdrvMailbox.payload < FRAMESIZE_INVALID)) {
|
||||
int reinit = 0;
|
||||
// if changinf from or to disabled, then force re-init.
|
||||
if (Settings->webcam_config.resolution == 15 || XdrvMailbox.payload == -1){
|
||||
// if changing from or to disabled, then force re-init.
|
||||
if (WcResolutionSetting() == -1 || XdrvMailbox.payload == -1){
|
||||
reinit = 1;
|
||||
}
|
||||
Settings->webcam_config.resolution = XdrvMailbox.payload;
|
||||
WcResolutionSetting(XdrvMailbox.payload);
|
||||
if (reinit) {
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
} else {
|
||||
WcSetOptions(0, Settings->webcam_config.resolution);
|
||||
WcSetOptions(0, WcResolutionSetting());
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Settings->webcam_config.resolution);
|
||||
ResponseCmndNumber(WcResolutionSetting());
|
||||
}
|
||||
|
||||
void CmndWebcamMirror(void) {
|
||||
@@ -2861,7 +2910,7 @@ void CmndWebcamClock(void){
|
||||
Settings->webcam_clk = XdrvMailbox.payload;
|
||||
// if cam is up, must setup to apply
|
||||
if (Wc.up){
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Settings->webcam_clk);
|
||||
@@ -2876,7 +2925,7 @@ void CmndWebcamCamStartStop(void){
|
||||
|
||||
|
||||
void CmndWebcamInit(void) {
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
WcSetStreamserver(Settings->webcam_config.stream);
|
||||
ResponseCmndDone();
|
||||
}
|
||||
@@ -3027,7 +3076,7 @@ bool Xdrv99(uint32_t function) {
|
||||
break;
|
||||
case FUNC_INIT:
|
||||
// starts stream server if configured, and configured camera
|
||||
WcSetup((int32_t)Settings->webcam_config.resolution);
|
||||
WcSetup((int32_t)WcResolutionSetting());
|
||||
WcSetStreamserver(Settings->webcam_config.stream);
|
||||
WCStartOperationTask();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user