initial rtsp support

#define ENABLE_RTSPSERVER
This commit is contained in:
gemu2015 2020-10-19 07:26:42 +02:00
parent a80a58c358
commit 586fee6745
1 changed files with 73 additions and 8 deletions

81
tasmota/xdrv_81_webcam.ino Normal file → Executable file
View File

@ -105,6 +105,19 @@ struct {
#endif #endif
} Wc; } Wc;
#ifdef ENABLE_RTSPSERVER
#include <OV2640.h>
#include <SimStreamer.h>
#include <OV2640Streamer.h>
#include <CRtspSession.h>
WiFiServer rtspServer(8554);
CStreamer *rtsp_streamer;
CRtspSession *rtsp_session;
WiFiClient rtsp_client;
uint8_t rtsp_start;
OV2640 cam;
#endif
/*********************************************************************************************/ /*********************************************************************************************/
bool WcPinUsed(void) { bool WcPinUsed(void) {
@ -199,7 +212,6 @@ uint32_t WcSetup(int32_t fsiz) {
//esp_log_level_set("*", ESP_LOG_INFO); //esp_log_level_set("*", ESP_LOG_INFO);
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer. // for larger pre-allocated frame buffer.
@ -216,11 +228,12 @@ uint32_t WcSetup(int32_t fsiz) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: PSRAM not found")); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: PSRAM not found"));
} }
// AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: heap check 1: %d"),ESP_getFreeHeap());
// stupid workaround camera diver eats up static ram should prefer PSRAM // stupid workaround camera diver eats up static ram should prefer PSRAM
// so we steal static ram to force driver to alloc PSRAM // so we steal static ram to force driver to alloc PSRAM
//ESP.getMaxAllocHeap() // uint32_t maxfram = ESP.getMaxAllocHeap();
// void *x=malloc(maxfram-4096);
// void *x=malloc(70000);
void *x = 0; void *x = 0;
esp_err_t err = esp_camera_init(&config); esp_err_t err = esp_camera_init(&config);
if (x) { free(x); } if (x) { free(x); }
@ -230,6 +243,8 @@ uint32_t WcSetup(int32_t fsiz) {
return 0; return 0;
} }
// AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: heap check 2: %d"),ESP_getFreeHeap());
sensor_t * wc_s = esp_camera_sensor_get(); sensor_t * wc_s = esp_camera_sensor_get();
wc_s->set_vflip(wc_s, Settings.webcam_config.flip); wc_s->set_vflip(wc_s, Settings.webcam_config.flip);
@ -819,11 +834,16 @@ uint32_t WcSetStreamserver(uint32_t flag) {
void WcStreamControl() { void WcStreamControl() {
WcSetStreamserver(Settings.webcam_config.stream); WcSetStreamserver(Settings.webcam_config.stream);
int resolution = (!Settings.webcam_config.stream) ? -1 : Settings.webcam_config.resolution; WcSetup(Settings.webcam_config.resolution);
WcSetup(resolution);
} }
/*********************************************************************************************/ /*********************************************************************************************/
#ifdef ENABLE_RTSPSERVER
static uint32_t rtsp_lastframe_time;
#ifndef RTSP_FRAME_TIME
#define RTSP_FRAME_TIME 100
#endif
#endif
void WcLoop(void) { void WcLoop(void) {
if (CamServer) { if (CamServer) {
@ -834,6 +854,45 @@ void WcLoop(void) {
#ifdef USE_FACE_DETECT #ifdef USE_FACE_DETECT
if (Wc.face_detect_time) { WcDetectFace(); } if (Wc.face_detect_time) { WcDetectFace(); }
#endif #endif
#ifdef ENABLE_RTSPSERVER
if (!rtsp_start && !global_state.wifi_down && Wc.up) {
rtspServer.begin();
rtsp_start = 1;
AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: RTSP init"));
rtsp_lastframe_time = millis();
}
// If we have an active client connection, just service that until gone
if (rtsp_session) {
rtsp_session->handleRequests(0); // we don't use a timeout here,
// instead we send only if we have new enough frames
uint32_t now = millis();
if ((now-rtsp_lastframe_time) > RTSP_FRAME_TIME) {
rtsp_session->broadcastCurrentFrame(now);
rtsp_lastframe_time = now;
// AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: RTSP session frame"));
}
if (rtsp_session->m_stopped) {
delete rtsp_session;
delete rtsp_streamer;
rtsp_session = NULL;
rtsp_streamer = NULL;
AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: RTSP stopped"));
}
}
else {
rtsp_client = rtspServer.accept();
if (rtsp_client) {
rtsp_streamer = new OV2640Streamer(&rtsp_client, cam); // our streamer for UDP/TCP based RTP transport
rtsp_session = new CRtspSession(&rtsp_client, rtsp_streamer); // our threads RTSP session and state
AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: RTSP stream created"));
}
}
#endif
} }
void WcPicSetup(void) { void WcPicSetup(void) {
@ -880,15 +939,16 @@ void WcInit(void) {
#define D_CMND_WC_SATURATION "Saturation" #define D_CMND_WC_SATURATION "Saturation"
#define D_CMND_WC_BRIGHTNESS "Brightness" #define D_CMND_WC_BRIGHTNESS "Brightness"
#define D_CMND_WC_CONTRAST "Contrast" #define D_CMND_WC_CONTRAST "Contrast"
#define D_CMND_WC_INIT "Init"
const char kWCCommands[] PROGMEM = D_PRFX_WEBCAM "|" // Prefix const char kWCCommands[] PROGMEM = D_PRFX_WEBCAM "|" // Prefix
"|" D_CMND_WC_STREAM "|" D_CMND_WC_RESOLUTION "|" D_CMND_WC_MIRROR "|" D_CMND_WC_FLIP "|" "|" D_CMND_WC_STREAM "|" D_CMND_WC_RESOLUTION "|" D_CMND_WC_MIRROR "|" D_CMND_WC_FLIP "|"
D_CMND_WC_SATURATION "|" D_CMND_WC_BRIGHTNESS "|" D_CMND_WC_CONTRAST D_CMND_WC_SATURATION "|" D_CMND_WC_BRIGHTNESS "|" D_CMND_WC_CONTRAST "|" D_CMND_WC_INIT
; ;
void (* const WCCommand[])(void) PROGMEM = { void (* const WCCommand[])(void) PROGMEM = {
&CmndWebcam, &CmndWebcamStream, &CmndWebcamResolution, &CmndWebcamMirror, &CmndWebcamFlip, &CmndWebcam, &CmndWebcamStream, &CmndWebcamResolution, &CmndWebcamMirror, &CmndWebcamFlip,
&CmndWebcamSaturation, &CmndWebcamBrightness, &CmndWebcamContrast &CmndWebcamSaturation, &CmndWebcamBrightness, &CmndWebcamContrast, &CmndWebcamInit
}; };
void CmndWebcam(void) { void CmndWebcam(void) {
@ -956,6 +1016,11 @@ void CmndWebcamContrast(void) {
ResponseCmndNumber(Settings.webcam_config.contrast -2); ResponseCmndNumber(Settings.webcam_config.contrast -2);
} }
void CmndWebcamInit(void) {
WcStreamControl();
ResponseCmndDone();
}
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/