mirror of
https://github.com/Motion-Project/motion.git
synced 2026-02-08 05:51:35 -05:00
329 lines
12 KiB
C++
329 lines
12 KiB
C++
/*
|
|
* This file is part of MotionPlus.
|
|
*
|
|
* MotionPlus is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* MotionPlus is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "motionplus.hpp"
|
|
#include "conf.hpp"
|
|
#include "logger.hpp"
|
|
#include "util.hpp"
|
|
#include "camera.hpp"
|
|
#include "picture.hpp"
|
|
#include "alg_sec.hpp"
|
|
#include "webu_getimg.hpp"
|
|
|
|
/* NOTE: These run on the camera thread. */
|
|
|
|
/* Initial the stream context items for the camera */
|
|
void webu_getimg_init(cls_camera *cam)
|
|
{
|
|
pthread_mutex_init(&cam->stream.mutex, NULL);
|
|
|
|
cam->imgs.image_substream = NULL;
|
|
|
|
cam->stream.norm.jpg_sz = 0;
|
|
cam->stream.norm.jpg_data = NULL;
|
|
cam->stream.norm.jpg_cnct = 0;
|
|
cam->stream.norm.ts_cnct = 0;
|
|
cam->stream.norm.all_cnct = 0;
|
|
cam->stream.norm.consumed = true;
|
|
cam->stream.norm.img_data = NULL;
|
|
|
|
cam->stream.sub.jpg_sz = 0;
|
|
cam->stream.sub.jpg_data = NULL;
|
|
cam->stream.sub.jpg_cnct = 0;
|
|
cam->stream.sub.ts_cnct = 0;
|
|
cam->stream.sub.all_cnct = 0;
|
|
cam->stream.sub.consumed = true;
|
|
cam->stream.sub.img_data = NULL;
|
|
|
|
cam->stream.motion.jpg_sz = 0;
|
|
cam->stream.motion.jpg_data = NULL;
|
|
cam->stream.motion.jpg_cnct = 0;
|
|
cam->stream.motion.ts_cnct = 0;
|
|
cam->stream.motion.all_cnct = 0;
|
|
cam->stream.motion.consumed = true;
|
|
cam->stream.motion.img_data = NULL;
|
|
|
|
cam->stream.source.jpg_sz = 0;
|
|
cam->stream.source.jpg_data = NULL;
|
|
cam->stream.source.jpg_cnct = 0;
|
|
cam->stream.source.ts_cnct = 0;
|
|
cam->stream.source.all_cnct = 0;
|
|
cam->stream.source.consumed = true;
|
|
cam->stream.source.img_data = NULL;
|
|
|
|
cam->stream.secondary.jpg_sz = 0;
|
|
cam->stream.secondary.jpg_data = NULL;
|
|
cam->stream.secondary.jpg_cnct = 0;
|
|
cam->stream.secondary.ts_cnct = 0;
|
|
cam->stream.secondary.all_cnct = 0;
|
|
cam->stream.secondary.consumed = true;
|
|
cam->stream.secondary.img_data = NULL;
|
|
|
|
}
|
|
|
|
/* Free the stream buffers and mutex for shutdown */
|
|
void webu_getimg_deinit(cls_camera *cam)
|
|
{
|
|
/* NOTE: This runs on the camera thread. */
|
|
myfree(cam->imgs.image_substream);
|
|
|
|
pthread_mutex_lock(&cam->stream.mutex);
|
|
myfree(cam->stream.norm.jpg_data);
|
|
myfree(cam->stream.sub.jpg_data);
|
|
myfree(cam->stream.motion.jpg_data);
|
|
myfree(cam->stream.source.jpg_data);
|
|
myfree(cam->stream.secondary.jpg_data);
|
|
|
|
myfree(cam->stream.norm.img_data) ;
|
|
myfree(cam->stream.sub.img_data) ;
|
|
myfree(cam->stream.motion.img_data) ;
|
|
myfree(cam->stream.source.img_data) ;
|
|
myfree(cam->stream.secondary.img_data) ;
|
|
pthread_mutex_unlock(&cam->stream.mutex);
|
|
|
|
pthread_mutex_destroy(&cam->stream.mutex);
|
|
|
|
}
|
|
|
|
/* Get a normal image from the motion loop and compress it*/
|
|
static void webu_getimg_norm(cls_camera *cam)
|
|
{
|
|
if ((cam->stream.norm.jpg_cnct == 0) &&
|
|
(cam->stream.norm.ts_cnct == 0) &&
|
|
(cam->stream.norm.all_cnct == 0)) {
|
|
return;
|
|
}
|
|
|
|
if (cam->stream.norm.jpg_cnct > 0) {
|
|
if (cam->stream.norm.jpg_data == NULL) {
|
|
cam->stream.norm.jpg_data =(unsigned char*)
|
|
mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
if (cam->current_image->image_norm != NULL && cam->stream.norm.consumed) {
|
|
cam->stream.norm.jpg_sz = cam->picture->put_memory(
|
|
cam->stream.norm.jpg_data
|
|
,cam->imgs.size_norm
|
|
,cam->current_image->image_norm
|
|
,cam->cfg->stream_quality
|
|
,cam->imgs.width
|
|
,cam->imgs.height);
|
|
cam->stream.norm.consumed = false;
|
|
}
|
|
}
|
|
if ((cam->stream.norm.ts_cnct > 0) || (cam->stream.norm.all_cnct > 0)) {
|
|
if (cam->stream.norm.img_data == NULL) {
|
|
cam->stream.norm.img_data =(unsigned char*)
|
|
mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
memcpy(cam->stream.norm.img_data, cam->current_image->image_norm
|
|
, (uint)cam->imgs.size_norm);
|
|
}
|
|
}
|
|
|
|
/* Get a substream image from the motion loop and compress it*/
|
|
static void webu_getimg_sub(cls_camera *cam)
|
|
{
|
|
int subsize;
|
|
|
|
if ((cam->stream.sub.jpg_cnct == 0) &&
|
|
(cam->stream.sub.ts_cnct == 0) &&
|
|
(cam->stream.sub.all_cnct == 0)) {
|
|
return;
|
|
}
|
|
|
|
if (cam->stream.sub.jpg_cnct > 0) {
|
|
if (cam->stream.sub.jpg_data == NULL) {
|
|
cam->stream.sub.jpg_data =(unsigned char*)
|
|
mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
if (cam->current_image->image_norm != NULL && cam->stream.sub.consumed) {
|
|
/* Resulting substream image must be multiple of 8 */
|
|
if (((cam->imgs.width % 16) == 0) &&
|
|
((cam->imgs.height % 16) == 0)) {
|
|
|
|
subsize = ((cam->imgs.width / 2) * (cam->imgs.height / 2) * 3 / 2);
|
|
if (cam->imgs.image_substream == NULL) {
|
|
cam->imgs.image_substream =(unsigned char*)
|
|
mymalloc((uint)subsize);
|
|
}
|
|
cam->picture->scale_img(cam->imgs.width
|
|
,cam->imgs.height
|
|
,cam->current_image->image_norm
|
|
,cam->imgs.image_substream);
|
|
cam->stream.sub.jpg_sz = cam->picture->put_memory(
|
|
cam->stream.sub.jpg_data
|
|
,subsize
|
|
,cam->imgs.image_substream
|
|
,cam->cfg->stream_quality
|
|
,(cam->imgs.width / 2)
|
|
,(cam->imgs.height / 2));
|
|
} else {
|
|
/* Substream was not multiple of 8 so send full image*/
|
|
cam->stream.sub.jpg_sz = cam->picture->put_memory(
|
|
cam->stream.sub.jpg_data
|
|
,cam->imgs.size_norm
|
|
,cam->current_image->image_norm
|
|
,cam->cfg->stream_quality
|
|
,cam->imgs.width
|
|
,cam->imgs.height);
|
|
}
|
|
cam->stream.sub.consumed = false;
|
|
}
|
|
}
|
|
|
|
if ((cam->stream.sub.ts_cnct > 0) || (cam->stream.sub.all_cnct > 0)) {
|
|
if (cam->stream.sub.img_data == NULL) {
|
|
cam->stream.sub.img_data =(unsigned char*)mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
if (((cam->imgs.width % 16) == 0) &&
|
|
((cam->imgs.height % 16) == 0)) {
|
|
subsize = ((cam->imgs.width / 2) * (cam->imgs.height / 2) * 3 / 2);
|
|
if (cam->imgs.image_substream == NULL) {
|
|
cam->imgs.image_substream =(unsigned char*)mymalloc((uint)subsize);
|
|
}
|
|
cam->picture->scale_img(cam->imgs.width
|
|
,cam->imgs.height
|
|
,cam->current_image->image_norm
|
|
,cam->imgs.image_substream);
|
|
memcpy(cam->stream.sub.img_data, cam->imgs.image_substream, (uint)subsize);
|
|
} else {
|
|
memcpy(cam->stream.sub.img_data, cam->current_image->image_norm
|
|
, (uint)cam->imgs.size_norm);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* Get a motion image from the motion loop and compress it*/
|
|
static void webu_getimg_motion(cls_camera *cam)
|
|
{
|
|
if ((cam->stream.motion.jpg_cnct == 0) &&
|
|
(cam->stream.motion.ts_cnct == 0) &&
|
|
(cam->stream.motion.all_cnct == 0)) {
|
|
return;
|
|
}
|
|
|
|
if (cam->stream.motion.jpg_cnct > 0) {
|
|
if (cam->stream.motion.jpg_data == NULL) {
|
|
cam->stream.motion.jpg_data =(unsigned char*)mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
if (cam->imgs.image_motion.image_norm != NULL && cam->stream.motion.consumed) {
|
|
cam->stream.motion.jpg_sz = cam->picture->put_memory(
|
|
cam->stream.motion.jpg_data
|
|
,cam->imgs.size_norm
|
|
,cam->imgs.image_motion.image_norm
|
|
,cam->cfg->stream_quality
|
|
,cam->imgs.width
|
|
,cam->imgs.height);
|
|
cam->stream.motion.consumed = false;
|
|
}
|
|
}
|
|
if ((cam->stream.motion.ts_cnct > 0) || (cam->stream.motion.all_cnct > 0)) {
|
|
if (cam->stream.motion.img_data == NULL) {
|
|
cam->stream.motion.img_data =(unsigned char*)mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
memcpy(cam->stream.motion.img_data
|
|
, cam->imgs.image_motion.image_norm
|
|
, (uint)cam->imgs.size_norm);
|
|
}
|
|
}
|
|
|
|
/* Get a source image from the motion loop and compress it*/
|
|
static void webu_getimg_source(cls_camera *cam)
|
|
{
|
|
if ((cam->stream.source.jpg_cnct == 0) &&
|
|
(cam->stream.source.ts_cnct == 0) &&
|
|
(cam->stream.source.all_cnct == 0)) {
|
|
return;
|
|
}
|
|
|
|
if (cam->stream.source.jpg_cnct > 0) {
|
|
if (cam->stream.source.jpg_data == NULL) {
|
|
cam->stream.source.jpg_data =(unsigned char*)mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
if (cam->imgs.image_virgin != NULL && cam->stream.source.consumed) {
|
|
cam->stream.source.jpg_sz = cam->picture->put_memory(
|
|
cam->stream.source.jpg_data
|
|
,cam->imgs.size_norm
|
|
,cam->imgs.image_virgin
|
|
,cam->cfg->stream_quality
|
|
,cam->imgs.width
|
|
,cam->imgs.height);
|
|
cam->stream.source.consumed = false;
|
|
}
|
|
}
|
|
if ((cam->stream.source.ts_cnct > 0) || (cam->stream.source.all_cnct > 0)) {
|
|
if (cam->stream.source.img_data == NULL) {
|
|
cam->stream.source.img_data =(unsigned char*)mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
memcpy(cam->stream.source.img_data
|
|
, cam->imgs.image_virgin
|
|
, (uint)cam->imgs.size_norm);
|
|
}
|
|
}
|
|
|
|
/* Get a secondary image from the motion loop and compress it*/
|
|
static void webu_getimg_secondary(cls_camera *cam)
|
|
{
|
|
if ((cam->stream.secondary.jpg_cnct == 0) &&
|
|
(cam->stream.secondary.ts_cnct == 0) &&
|
|
(cam->stream.secondary.all_cnct == 0)) {
|
|
return;
|
|
}
|
|
|
|
if (cam->stream.secondary.jpg_cnct > 0) {
|
|
if (cam->imgs.size_secondary>0) {
|
|
pthread_mutex_lock(&cam->algsec->mutex);
|
|
if (cam->stream.secondary.jpg_data == NULL) {
|
|
cam->stream.secondary.jpg_data =(unsigned char*)
|
|
mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
|
|
memcpy(cam->stream.secondary.jpg_data
|
|
, cam->imgs.image_secondary
|
|
, (uint)cam->imgs.size_secondary);
|
|
cam->stream.secondary.jpg_sz = cam->imgs.size_secondary;
|
|
pthread_mutex_unlock(&cam->algsec->mutex);
|
|
} else {
|
|
myfree(cam->stream.secondary.jpg_data);
|
|
}
|
|
}
|
|
if ((cam->stream.secondary.ts_cnct > 0) || (cam->stream.secondary.all_cnct > 0)) {
|
|
if (cam->stream.secondary.img_data == NULL) {
|
|
cam->stream.secondary.img_data =(unsigned char*)
|
|
mymalloc((uint)cam->imgs.size_norm);
|
|
}
|
|
memcpy(cam->stream.secondary.img_data
|
|
, cam->current_image->image_norm, (uint)cam->imgs.size_norm);
|
|
}
|
|
|
|
}
|
|
|
|
/* Get image from the motion loop and compress it*/
|
|
void webu_getimg_main(cls_camera *cam)
|
|
{
|
|
/*This is on the camera thread */
|
|
pthread_mutex_lock(&cam->stream.mutex);
|
|
webu_getimg_norm(cam);
|
|
webu_getimg_sub(cam);
|
|
webu_getimg_motion(cam);
|
|
webu_getimg_source(cam);
|
|
webu_getimg_secondary(cam);
|
|
pthread_mutex_unlock(&cam->stream.mutex);
|
|
}
|