Files
motion/src/webu_getimg.cpp

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);
}