doubao_chat/apps/wifi_ipc/wifi/stream/video_rt_usr.c

305 lines
8.4 KiB
C

#include "app_config.h"
#include "system/sys_common.h"
#include "server/rt_stream_pkg.h"
#include "stream_core.h"
#include "sock_api/sock_api.h"
#include "get_yuv_data.h"
#ifdef CONFIG_VIDEO_ENABLE
#ifdef CONFIG_QR_CODE_NET_CFG
#include "asm/jpeg_codec.h"
#include "qrcode/qrcode.h"
#include "json_c/json_tokener.h"
#include "mbedtls/base64.h"
#endif
extern int qr_code_net_set_ssid_pwd(const char *ssid, const char *pwd);
extern int page_turning_recognition(void *data, u32 length, u8 buf_copy);
extern u8 page_turning_get_mode(void);
extern u8 get_turing_ocr_flag(void);
extern u8 get_turing_finger_flag(void);
extern u8 is_in_config_network_state(void);
extern u32 timer_get_ms(void);
#ifdef CONFIG_PAGE_TURNING_DET_ENABLE
static jl_ptd_t jl_ptd;
static u32 page_tri_time;
static u8 page_tri;
#endif
#ifdef CONFIG_TURING_PAGE_TURNING_DET_ENABLE
static MotionDetection md;
#endif
#ifdef CONFIG_QR_CODE_NET_CFG
static void *qr_decoder;
static u8 qr_flag;
#ifdef CONFIG_TURING_SDK_ENABLE
static char turing_openid[12];
const char *get_qrcode_result_openid(void)
{
return turing_openid[0] ? turing_openid : NULL;
}
#endif
void qr_code_net_cfg_start(void)
{
#ifdef CONFIG_TURING_SDK_ENABLE
memset(turing_openid, 0, sizeof(turing_openid));
#endif
qr_flag = 1;
qr_decoder = qrcode_init(QR_FRAME_W, QR_FRAME_H, QR_FRAME_W, QRCODE_MODE_NORMAL, 150, SYM_QRCODE, 1);
}
void qr_code_net_cfg_stop(void)
{
if (qr_decoder) {
qrcode_deinit(qr_decoder);
qr_decoder = NULL;
}
}
static int qr_code_net_cfg_process(void *qr_decoder, u8 *inputFrame)
{
int ret = -1, type = 0;
char *buf = NULL;
int buf_size = 0;
int md_detected = 0; //是否检测到运动物体
json_object *new_obj = NULL;
json_object *key = NULL;
if (qr_decoder) {
qrcode_detectAndDecode(qr_decoder, inputFrame, &md_detected);
ret = qrcode_get_result(qr_decoder, &buf, &buf_size);
type = qrcode_get_symbol_type(qr_decoder);
if (buf_size > 0 && ret == 0) {
buf[buf_size] = 0;
#ifdef CONFIG_TURING_SDK_ENABLE
unsigned long olen = 0;
ret = mbedtls_base64_decode((u8 *)buf, strlen(buf), &olen, (u8 *)buf, strlen(buf));
if (ret) {
return -1;
}
buf[olen] = 0;
#endif
printf("qr code type = %d decode: %s\n", type, buf);
new_obj = json_tokener_parse(buf);
if (!new_obj) {
goto __exit;
}
const char *str_ssid = json_object_get_string(json_object_object_get(new_obj, "ssid"));
if (str_ssid) {
printf("qr code net config ssid : %s\n", str_ssid);
} else {
goto __exit;
}
#ifdef CONFIG_TURING_SDK_ENABLE
const char *openid = json_object_get_string(json_object_object_get(new_obj, "TuringBindID"));
if (openid) {
snprintf(turing_openid, sizeof(turing_openid), "%s", openid);
}
const char *str_pwd = json_object_get_string(json_object_object_get(new_obj, "pwd"));
#else
const char *str_pwd = json_object_get_string(json_object_object_get(new_obj, "pass"));
#endif
if (str_pwd) {
printf("qr code net config pwd : %s\n", str_pwd);
} else {
str_pwd = "";
}
qr_code_net_set_ssid_pwd(str_ssid, str_pwd);
ret = 0;
qr_flag = 0;
}
}
__exit:
if (new_obj) {
json_object_put(new_obj);
}
return ret;
}
static void cvHalfYUV420(unsigned char *dataSrc, unsigned char *dataDst, int srcHeight, int srcWidth)
{
//support YUV420
int i = 0;
for (int y = 0; y < srcHeight; y += 2) {
for (int x = 0; x < srcWidth; x += 2) {
dataDst[i] = dataSrc[y * srcWidth + x];
i++;
}
}
for (int y = 0; y < srcHeight / 2; y += 2) {
for (int x = 0; x < srcWidth; x += 4) {
dataDst[i] = dataSrc[(srcWidth * srcHeight) + (y * srcWidth) + x];
i++;
dataDst[i] = dataSrc[(srcWidth * srcHeight) + (y * srcWidth) + (x + 1)];
i++;
}
}
}
#endif
static void get_one_frame(u8 *inputFrame, u32 len, int width, int height)
{
#ifdef CONFIG_QR_CODE_NET_CFG
if (is_in_config_network_state()) {
if (qr_decoder && qr_flag) {
#if 1
cvHalfYUV420(inputFrame, inputFrame, height, width);
#else
extern int YUV420p_Soft_Scaling(unsigned char *src, unsigned char *out, int src_w, int src_h, int out_w, int out_h);
YUV420p_Soft_Scaling(inputFrame, inputFrame, width, height, width / 2, height / 2);
#endif
qr_code_net_cfg_process(qr_decoder, inputFrame);
}
}
#endif
#ifdef CONFIG_PAGE_TURNING_DET_ENABLE
if (page_turning_get_mode() == PICTURE_DET_ENTER_MODE && ptd_process(&jl_ptd, inputFrame)) {
page_tri = 1;
page_tri_time = timer_get_ms();
}
#endif
#ifdef CONFIG_TURING_PAGE_TURNING_DET_ENABLE
if (page_turning_get_mode() == PICTURE_DET_ENTER_MODE) {
u8 ocr_flag = get_turing_ocr_flag();
u8 finger_flag = get_turing_finger_flag();
unsigned char *outImg = getMotionResult(&md, inputFrame, width, height, 1, TL_CV_YUV2GRAY_420, timer_get_ms(), ocr_flag, finger_flag);
if (outImg) {
struct jpeg_encode_req req = {0};
u32 buf_len = ocr_flag ? 60 * 1024 : 30 * 1024;
u8 *jpg_img = malloc(buf_len);
if (!jpg_img) {
puts("jpeg buf not enough !!!\n");
return;
}
//q >=2 , size = w*h*q*0.32
req.q = 5; //jepg编码质量(范围0-13),质量越好,下面的编码buf需要适当增大
req.format = JPG_SAMP_FMT_YUV420;
req.data.buf = jpg_img;
req.data.len = buf_len;
req.width = ocr_flag ? width : (width / 2);
req.height = ocr_flag ? height : (height / 2);
req.y = outImg;
req.u = req.y + req.width * req.height;
req.v = req.u + req.width * req.height / 4;
if (0 == jpeg_encode_one_image(&req)) {
printf("jpeg_encode_one_image ok \n\n");
if (0 != page_turning_recognition(req.data.buf, req.data.len, 0)) {
free(jpg_img);
}
}
}
}
#endif
}
int page_turning_det_uninit(void)
{
get_yuv_uninit();
#ifdef CONFIG_PAGE_TURNING_DET_ENABLE
ptd_deinit(&jl_ptd);
#endif
#ifdef CONFIG_TURING_PAGE_TURNING_DET_ENABLE
cvFreeImageTL(md.frame1);
#endif
return 0;
}
#ifdef CONFIG_QR_CODE_NET_CFG
void config_network_get_yuv_init(void)
{
get_yuv_init(get_one_frame);
}
void config_network_get_yuv_uninit(void)
{
get_yuv_uninit();
}
#endif
static u32(*video_rt_cb)(void *, u8 *, u32);
static void *cb_priv;
void set_video_rt_cb(u32(*cb)(void *, u8 *, u32), void *priv)
{
video_rt_cb = cb;
cb_priv = priv;
}
static void *video_rt_usr_init(const char *path, const char *mode)
{
//连接服务器操作
puts("video_rt_usr_init\n");
struct rt_stream_info *r_info = calloc(1, sizeof(struct rt_stream_info));
if (r_info == NULL) {
printf("%s malloc fail\n", __FILE__);
return NULL;
}
return (void *)r_info;
}
static int video_rt_usr_send(void *hdr, void *data, u32 len, u8 type)
{
struct rt_stream_info *r_info = (struct rt_stream_info *)hdr;
if (video_rt_cb) {
video_rt_cb(cb_priv, data, len);
}
#ifdef CONFIG_PAGE_TURNING_DET_ENABLE
static u32 recognition_time = 0;
static u32 timehdl;
u32 dtime;
if (type == JPEG_TYPE_VIDEO && page_turning_get_mode() == PICTURE_DET_ENTER_MODE) {
if (page_tri) {
dtime = timer_get_ms() - page_tri_time;
//翻页时间已经过去500s并且上次距离上次识别已经过去500ms
if (dtime > 500 && (timer_get_ms() - recognition_time) > 500) {
if (0 == page_turning_recognition(data, len, 1)) {
recognition_time = timer_get_ms();
page_tri = 0;
}
}
}
}
#endif
return len;
}
static int video_rt_usr_uninit(void *hdr)
{
puts("video_rt_usr_uninit\n\n\n\n\n\n");
struct rt_stream_info *r_info = (struct rt_stream_info *)hdr;
free(r_info);
return 0;
}
REGISTER_NET_VIDEO_STREAM_SUDDEV(usr_video_stream_sub) = {
.name = "usr",
.open = video_rt_usr_init,
.write = video_rt_usr_send,
.close = video_rt_usr_uninit,
};
#endif