rk3568_ubuntu_r60_v1.3.2/external/rkfacial/snapshot.c
2023-11-03 06:12:44 +00:00

197 lines
5.5 KiB
C

/*
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
* author: Zhihua Wang, hogan.wang@rock-chips.com
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL), available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "snapshot.h"
#include <sys/time.h>
#define SNAP_ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
int snapshot_init(struct snapshot *s, int w, int h)
{
if (s->size)
return 0;
if (rga_control_buffer_init_nocache(&s->nv12_bo, &s->nv12_fd, w, h, 12))
return -1;
if (rga_control_buffer_init_nocache(&s->enc_bo, &s->enc_fd, w, h, 12))
return -1;
s->size = w * h * 3 / 2;
return 0;
}
void snapshot_exit(struct snapshot *s)
{
if (s->size) {
rga_control_buffer_deinit(&s->nv12_bo, s->nv12_fd);
rga_control_buffer_deinit(&s->enc_bo, s->enc_fd);
}
}
void face_convert(rockface_det_t face, int *x, int *y, int *w, int *h, int width, int height)
{
int temp;
/* expand face region 50% */
temp = (face.box.right - face.box.left) / 4;
face.box.left -= temp;
face.box.right += temp;
temp = (face.box.bottom - face.box.top) / 4;
face.box.top -= temp;
face.box.bottom += temp;
if (face.box.left <= 0)
face.box.left = 0;
if (face.box.right >= width)
face.box.right = width - 1;
if (face.box.top <= 0)
face.box.top = 0;
if (face.box.bottom >= height)
face.box.bottom = height - 1;
*w = face.box.right - face.box.left;
*h = face.box.bottom - face.box.top;
*w = SNAP_ALIGN(*w, 16);
*h = SNAP_ALIGN(*h, 16);
if (*w > width)
*w = width;
if (*h > height)
*h = height;
if (face.box.left + (*w) >= width)
*x = face.box.right - (*w);
else
*x = face.box.left;
if (face.box.top + (*h) >= height)
*y = face.box.bottom - (*h);
else
*y = face.box.top;
*x = SNAP_ALIGN(*x, 2);
*y = SNAP_ALIGN(*y, 2);
if (*x < 0)
*x = 0;
if (*y < 0)
*y = 0;
}
int snapshot_run(struct snapshot *s, rockface_image_t *image, rockface_det_t *face,
RgaSURF_FORMAT fmt, long int sec, char mark)
{
FILE *fp;
rga_info_t src, dst;
int w, h;
int x, y;
void *buffer = image->data;
int width = image->width;
int height = image->height;
if (!strlen(g_snapshot))
return -1;
if (snapshot_init(s, width, height))
return -1;
if (width * height * 3 / 2 > s->size)
return -1;
if (sec) {
if (!s->t0.tv_sec && !s->t0.tv_usec) {
gettimeofday(&s->t0, NULL);
} else {
gettimeofday(&s->t1, NULL);
if (s->t1.tv_sec - s->t0.tv_sec < sec)
return -1;
else
gettimeofday(&s->t0, NULL);
}
} else {
gettimeofday(&s->t0, NULL);
}
if (!strlen(s->name)) {
if (mark)
snprintf(s->name, sizeof(s->name), "%s/%c%ld.%06ld.jpg",
g_snapshot, mark, s->t0.tv_sec, s->t0.tv_usec);
else
snprintf(s->name, sizeof(s->name), "%s/%ld.%06ld.jpg",
g_snapshot, s->t0.tv_sec, s->t0.tv_usec);
}
if (face) {
face_convert(*face, &x, &y, &w, &h, width, height);
if (!w || !h)
return -1;
} else {
w = width;
h = height;
x = 0;
y = 0;
}
if (vpu_encode_jpeg_init(&s->enc, w, h, 7, MPP_FMT_YUV420SP))
return -1;
memset(&src, 0, sizeof(rga_info_t));
src.fd = -1;
src.virAddr = buffer;
src.mmuFlag = 1;
rga_set_rect(&src.rect, x, y, w, h, width, height, fmt);
memset(&dst, 0, sizeof(rga_info_t));
dst.fd = -1;
dst.virAddr = s->nv12_bo.ptr;
dst.mmuFlag = 1;
rga_set_rect(&dst.rect, 0, 0, w, h, w, h, RK_FORMAT_YCbCr_420_SP);
if (c_RkRgaBlit(&src, &dst, NULL)) {
printf("%s: rga fail\n", __func__);
return -1;
}
vpu_encode_jpeg_doing(&s->enc, s->nv12_bo.ptr, s->nv12_fd, w * h * 3 / 2,
s->enc_bo.ptr, s->enc_fd, s->size);
fp = fopen(s->name, "wb");
if (fp) {
fwrite(s->enc.enc_out_data, 1, s->enc.enc_out_length, fp);
fclose(fp);
printf("%s: save %s ok!\n", __func__, s->name);
} else {
printf("%s: open %s fail!\n", __func__, s->name);
}
vpu_encode_jpeg_done(&s->enc);
return 0;
}