doubao_chat/apps/wifi_ipc/wifi/net_video_rec.c

1751 lines
49 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "system/includes.h"
#include "server/video_server.h"
#include "server/video_engine_server.h"
#include "net_video_rec.h"
#include "strm_video_rec.h"
#include "action.h"
#include "app_config.h"
#include "asm/debug.h"
#include "asm/osd.h"
#include "app_database.h"
#include "storage_device.h"
#include "server/ctp_server.h"
#include "os/os_api.h"
#include "net_server.h"
#include "server/net_server.h"
#include "stream_protocol.h"
#include "event/device_event.h"
#include "event/net_event.h"
#include "event/key_event.h"
#include "net/config_network.h"
extern int pthread_mutex_unlock(int *mutex);
/******************************************/
/*tiny code*/
extern int db_select(const char *name);
extern int db_update(const char *name, u32 value);
/******************************************/
void net_video_server_init(void);
static int net_rt_video1_open(struct intent *it);
static int net_rt_video0_open(struct intent *it);
static int net_video_rec_start(u8 mark);
static int net_video_rec_stop(u8 close);
static int net_video_rec0_ch2_stop(u8 close);
static int net_video_rec1_ch2_stop(u8 close);
static int net_video_rec1_stop(u8 close);
static int net_video_rec_take_photo(void (*callback)(char *buffer, int len));
static int net_video_rec_get_abr(u32 width);
static int net_video_rec_alloc_buf(void);
static void net_video_rec_free_buf(void);
#define AUDIO_VOLUME 100
#define NET_VIDEO_REC_SERVER_NAME "net_video_server"
#define TAKE_PHOTO_MEM_LEN 40 * 1024
#define NET_VIDEO_ERR(x) {if(x) printf("######## %s %d err !!!! \n\n\n",__func__,__LINE__);}
static int net_rt_video0_stop(struct intent *it);
static int net_rt_video1_stop(struct intent *it);
static int net_video_rec_control(void *_run_cmd);
static const unsigned char net_osd_format_buf[] = "yyyy-nn-dd hh:mm:ss";
static int net_vd_msg[2];
static const u16 net_rec_pix_w[] = {1280, 640};
static const u16 net_rec_pix_h[] = {720, 480};
static struct net_video_hdl net_rec_handler = {0};
static struct strm_video_hdl *fv_rec_handler = NULL;
static struct video_rec_hdl *rec_handler = NULL;
#define __this_net (&net_rec_handler)
#define __this_strm (fv_rec_handler)
#define __this (rec_handler)
static OS_MUTEX net_vdrec_mutex;
#ifndef CONFIG_VIDEO0_ENABLE
#undef NET_VREC0_FBUF_SIZE
#define NET_VREC0_FBUF_SIZE 0
#endif
#ifndef CONFIG_VIDEO1_ENABLE
#undef NET_VREC1_FBUF_SIZE
#define NET_VREC1_FBUF_SIZE 0
#endif
#if NET_VREC0_FBUF_SIZE
#if (defined CONFIG_NET_TCP_ENABLE || defined CONFIG_NET_UDP_ENABLE || defined CONFIG_VIDEO_720P)
//内部sram只用静态buff
#define USE_STATIC_BUFF 1// 0 malloc , 1 static
#else
#define USE_STATIC_BUFF 0// 0 malloc , 1 static
#endif
#endif
#if (defined CONFIG_IPERF_ENABLE) && (defined CONFIG_NO_SDRAM_ENABLE) //无sdram开iperf测试内存需要130K,去掉静态留出内存
#undef USE_STATIC_BUFF
#define USE_STATIC_BUFF 0
#endif
#ifdef CONFIG_VIDEO_720P
#define NET_ISC_SBUF_SIZE (CONFIG_VIDEO_IMAGE_W*64*3/2)/*720P内部ISC BUFF采用内部ram*/
#else
#define NET_ISC_SBUF_SIZE (CONFIG_VIDEO_IMAGE_W*32*3/2)/*720P内部ISC BUFF采用内部ram*/
#endif
#ifdef CONFIG_VIDEO_720P
#define CAP_IMG_SIZE (150*1024)
#else
#define CAP_IMG_SIZE (40*1024)
#endif
#if USE_STATIC_BUFF
u8 net_video_buf[NET_VREC0_FBUF_SIZE] ALIGNE(4);
u8 net_audio_buf[NET_AUDIO_BUF_SIZE] ALIGNE(4);
u8 net_isc_sbuf[NET_ISC_SBUF_SIZE] SEC(.sram) ALIGNE(32);//必须32对齐
#endif
/*
*start user net video rec , 必须在app_config.h配置宏CONFIG_NET_USR_ENABLE 和NET_USR_PATH
*/
int user_net_video_rec_open(char forward)
{
int ret;
u8 open = 2;//char type : 0 audio , 1 video , 2 audio and video
struct intent it = {0};
struct rt_stream_app_info info = {0};
info.width = CONFIG_VIDEO_IMAGE_W;
info.height = CONFIG_VIDEO_IMAGE_H;
//帧率 app_config.h : NET_VIDEO_REC_FPS0/NET_VIDEO_REC_FPS1
it.data = &open;
it.exdata = (u32)&info;
if (__this_net->is_open) {
return 0;
}
__this_net->is_open = TRUE;
if (forward) {
ret = net_rt_video0_open(&it);
if (ret) {
__this_net->is_open = FALSE;
}
}
return ret;
}
int user_net_video_rec_close(char forward)
{
int ret = 0;
struct intent it = {0};
u8 close = 2;//char type : 0 audio , 1 video , 2 audio and video
it.data = &close;
if (!__this_net->is_open) {
return 0;
}
if (forward) {
ret = net_rt_video0_stop(&it);
}
__this_net->is_open = FALSE;
return ret;
}
void user_net_video_rec_take_photo_cb(char *buf, int len)//必须打开user_net_video_rec_open()
{
if (buf && len) {
printf("take photo success \n");
put_buf(buf, 32);
/*
//目录1写卡例子
FILE *fd = fopen(CAMERA0_CAP_PATH"IMG_***.jpg","w+");
if (fd) {
fwrite(fd,buf,len);
fclose(fd);
}
*/
}
}
//qua : 0 240p, 1 480p, 2 720p
int user_net_video_rec_take_photo(int qua, void (*callback)(char *buf, int len))//必须打开user_net_video_rec_open()
{
db_update("qua", qua);
net_video_rec_take_photo(callback);
return 0;
}
//example 720P: user_net_video_rec_take_photo(2, user_net_video_rec_take_photo_cb);
int user_net_video_rec_take_photo_test(void)
{
user_net_video_rec_take_photo(2, user_net_video_rec_take_photo_cb);
return 0;
}
/*
*end of user net video rec
*/
int net_video_rec_get_list_vframe(void)
{
return __this_net->fbuf_fcnt;
}
void net_video_rec_pkg_get_video_in_frame(char *fbuf, u32 frame_size)
{
__this_net->fbuf_fcnt++;
__this_net->fbuf_ffil += frame_size;
}
void net_video_rec_pkg_get_video_out_frame(char *fbuf, u32 frame_size)
{
if (__this_net->fbuf_fcnt) {
__this_net->fbuf_fcnt--;
}
if (__this_net->fbuf_ffil) {
__this_net->fbuf_ffil -= frame_size;
}
}
static void net_video_handler_init(void)
{
if (!fv_rec_handler) {
fv_rec_handler = (struct strm_video_hdl *)get_strm_video_rec_handler();
}
if (!rec_handler) {
rec_handler = (struct video_rec_hdl *)get_video_rec_handler();
}
}
void *get_net_video_rec_handler(void)
{
return (void *)&net_rec_handler;
}
void *get_video_rec0_handler(void)
{
if (!__this) {
return NULL;
}
return (void *)__this->video_rec0;
}
void *get_video_rec1_handler(void)
{
if (!__this) {
return NULL;
}
#ifdef CONFIG_VIDEO1_ENABLE
return (void *)__this->video_rec1;
#endif
#ifdef CONFIG_VIDEO2_ENABLE
return (void *)__this->video_rec2;
#endif
return NULL;
}
int net_video_rec_state(void)//获取录像状态,返回值大于0(1280/640)成功,失败 0
{
int res = db_select("res");
res = (res > 1 || res < 0) ? 1 : res;
if (__this && __this->state == VIDREC_STA_START) {
return net_rec_pix_w[res];
}
return 0;
}
int net_video_rec_uvc_online(void)
{
return dev_online("uvc");
}
int net_pkg_get_video_size(int *width, int *height)
{
u8 id = __this_net->video_id ? 1 : 0;
*width = __this_net->net_videoreq[id].rec.width;
*height = __this_net->net_videoreq[id].rec.height;
return 0;
}
int net_video_buff_set_frame_cnt(void)
{
#ifdef NET_VIDEO_BUFF_FRAME_CNT
return NET_VIDEO_BUFF_FRAME_CNT;
#else
return 0;
#endif
}
u8 net_video_rec_get_drop_fp(void)
{
#ifdef NET_VIDEO_REC_DROP_REAl_FP
return NET_VIDEO_REC_DROP_REAl_FP;
#else
return 0;
#endif
}
u8 net_video_rec_get_lose_fram(void)
{
#ifdef NET_VIDEO_REC_LOSE_FRAME_CNT
return NET_VIDEO_REC_LOSE_FRAME_CNT;
#else
return 0;
#endif
}
u8 net_video_rec_get_send_fram(void)
{
#ifdef NET_VIDEO_REC_SEND_FRAME_CNT
return NET_VIDEO_REC_SEND_FRAME_CNT;
#else
return 0;
#endif
}
int net_video_rec_get_fps(void)
{
int ret;
int fp = 15;
ret = net_video_rec_state();
if (ret) {
fp = VIDEO_REC_FPS;
} else {
if (!__this_net->video_id) {
fp = NET_VIDEO_REC_FPS0;
} else {
fp = NET_VIDEO_REC_FPS1;
}
}
ret = fp ? fp : 20;
return ret;
}
void net_video_rec_post_msg(const char *msg, ...)
{
#ifdef CONFIG_UI_ENABLE
/*
union uireq req;
va_list argptr;
va_start(argptr, msg);
if (__this->ui) {
req.msg.receiver = ID_WINDOW_VIDEO_REC;
req.msg.msg = msg;
req.msg.exdata = argptr;
server_request(__this->ui, UI_REQ_MSG, &req);
}
va_end(argptr);
*/
#endif
}
void net_video_rec_fmt_notify(void)
{
char buf[32];
#if defined CONFIG_ENABLE_VLIST
extern void FILE_DELETE(char *__fname, u8 create_file);
FILE_DELETE(NULL, __this_net->is_open);
sprintf(buf, "frm:1");
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "FORMAT", "NOTIFY", buf);
#endif
}
char *video_rec_finish_get_name(FILE *fd, int index, u8 is_emf) //index :video0前视0,video1则1,video2则2 , is_emf 紧急文件
{
static char path[64] ALIGNE(32) = {0};
u8 name[64];
u8 *dir;
int err;
#ifdef CONFIG_ENABLE_VLIST
memset(path, 0, sizeof(path));
err = fget_name(fd, name, 64);
/*printf("finish_get_name: %s \n", name);*/
if (err <= 0) {
return NULL;
}
if (index < 0) {
strcpy(path, name);
return path;
}
switch (index) {
case 0:
dir = CONFIG_REC_PATH_0;
break;
case 1:
dir = CONFIG_REC_PATH_1;
break;
case 2:
dir = CONFIG_REC_PATH_2;
break;
default:
return NULL;
}
#ifdef CONFIG_EMR_DIR_ENABLE
if (is_emf) {
sprintf(path, "%s%s%s", dir, CONFIG_EMR_REC_DIR, name);
} else
#endif
{
sprintf(path, "%s%s", dir, name);
}
return path;
#else
return NULL;
#endif
}
int video_rec_finish_notify(char *path)
{
int err = 0;
if (__this_net->video_rec_err) {
__this_net->video_rec_err = FALSE;
return 0;
}
os_mutex_pend(&net_vdrec_mutex, 0);
#ifdef CONFIG_ENABLE_VLIST
FILE_LIST_ADD(0, (const char *)path, __this_net->is_open);
#endif
os_mutex_post(&net_vdrec_mutex);
return err;
}
int video_rec_delect_notify(FILE *fd, int id)
{
int err = 0;
if (__this_net->video_rec_err) {
__this_net->video_rec_err = FALSE;
return 0;
}
#ifdef CONFIG_ENABLE_VLIST
char *delect_path;
os_mutex_pend(&net_vdrec_mutex, 0);
char *path = video_rec_finish_get_name(fd, id, 0);
if (path == NULL) {
os_mutex_post(&net_vdrec_mutex);
return -1;
}
FILE_DELETE((const char *)path, __this_net->is_open);
os_mutex_post(&net_vdrec_mutex);
#endif
return err;
}
int video_rec_err_notify(const char *method)
{
int err = 0;
char *err_path;
os_mutex_pend(&net_vdrec_mutex, 0);
if (method && !strcmp((const char *)method, "VIDEO_REC_ERR")) {
__this_net->video_rec_err = TRUE;
}
os_mutex_post(&net_vdrec_mutex);
return err;
}
int video_rec_state_notify(void)
{
int err = 0;
net_vd_msg[0] = NET_VIDREC_STATE_NOTIFY;
err = os_taskq_post_msg(NET_VIDEO_REC_SERVER_NAME, 1, (int)net_vd_msg);
return err;
}
int video_rec_start_notify(void)
{
return net_video_rec_control(0);//启动录像之前需要关闭实时流
}
int video_rec_all_stop_notify(void)
{
int err = 0;
net_vd_msg[0] = NET_VIDREC_STA_STOP;
err = os_taskq_post_msg(NET_VIDEO_REC_SERVER_NAME, 1, (int)net_vd_msg);
return err;
}
void net_video_rec_status_notify(void)
{
char buf[128];
u8 sta = 0;
if (__this && __this->state == VIDREC_STA_START) {
sta = 1;
}
memset(buf, 0, sizeof(buf));
sprintf(buf, "status:%d", sta);
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "VIDEO_CTRL", "NOTIFY", buf);
}
int net_video_rec_event_notify(void)
{
char buf[128];
int res = db_select("res2");
res = res > 0 ? res : 0;
#ifdef CONFIG_VIDEO1_ENABLE
#ifdef CONFIG_SPI_VIDEO_ENABLE
extern int spi_camera_width_get(void);
extern int spi_camera_height_get(void);
sprintf(buf, "status:1,h:%d,w:%d,fps:%d,rate:%d,format:1", spi_camera_height_get(), spi_camera_width_get(), 15, net_video_rec_get_audio_rate());
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "PULL_VIDEO_STATUS", "NOTIFY", buf);
return 0;
#endif
if (dev_online("video1"))
#else
#ifdef CONFIG_VIDEO2_ENABLE
if (dev_online("uvc"))
#else
if (0)
#endif
#endif
{
switch (res) {
case VIDEO_RES_1080P:
sprintf(buf, "status:1,h:%d,w:%d,fps:%d,rate:%d,format:1", 720, 1280, net_video_rec_get_fps(), net_video_rec_get_audio_rate());
break;
case VIDEO_RES_720P:
sprintf(buf, "status:1,h:%d,w:%d,fps:%d,rate:%d,format:1", 480, 640, net_video_rec_get_fps(), net_video_rec_get_audio_rate());
break;
case VIDEO_RES_VGA:
sprintf(buf, "status:1,h:%d,w:%d,fps:%d,rate:%d,format:1", 480, 640, net_video_rec_get_fps(), net_video_rec_get_audio_rate());
break;
default:
sprintf(buf, "status:1,h:%d,w:%d,fps:%d,rate:%d,format:1", 480, 640, net_video_rec_get_fps(), net_video_rec_get_audio_rate());
break;
}
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "PULL_VIDEO_STATUS", "NOTIFY", buf);
} else {
strcpy(buf, "status:0");
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "PULL_VIDEO_STATUS", "NOTIFY", buf);
}
return 0;
}
int net_video_rec_event_stop(void)
{
net_video_rec_stop(1);
return 0;
}
int net_video_rec_event_start(void)
{
net_rt_video0_open(NULL);
return 0;
}
int video_rec_sd_event_ctp_notify(char state)
{
char buf[128];
printf("~~~ : %s , %d\n\n", __func__, state);
#if defined CONFIG_ENABLE_VLIST
if (!state) {
FILE_REMOVE_ALL();
}
#endif
sprintf(buf, "online:%d", state);
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "SD_STATUS", "NOTIFY", buf);
if (state) {
u32 space = 0;
struct vfs_partition *part = NULL;
if (storage_device_ready() == 0) {
msleep(200);
if (storage_device_ready()) {
goto sd_scan;
}
printf("---%s , storage_device_not_ready !!!!\n\n", __func__);
CTP_CMD_COMBINED(NULL, CTP_SD_OFFLINE, "TF_CAP", "NOTIFY", CTP_SD_OFFLINE_MSG);
} else {
sd_scan:
part = fget_partition(CONFIG_ROOT_PATH);
fget_free_space(CONFIG_ROOT_PATH, &space);
sprintf(buf, "left:%d,total:%d", space / 1024, part->total_size / 1024);
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "TF_CAP", "NOTIFY", buf);
}
}
return 0;
}
//NET USE API
static void video_rec_get_app_status(struct intent *it)
{
it->data = (const char *)__this;
it->exdata = (u32)__this_net;
}
static void ctp_cmd_notity(const char *path)
{
#if defined CONFIG_ENABLE_VLIST
FILE_LIST_ADD(0, path, __this_net->is_open);
#endif
}
int net_video_rec_get_audio_rate()
{
return VIDEO_REC_AUDIO_SAMPLE_RATE;
}
int video_rec_cap_photo(char *buf, int len)
{
u32 *flen;
u8 *cap_img;
if (__this_net->cap_image) {
cap_img = &__this_net->cap_image;
} else {
cap_img = &__this_strm->cap_image;
}
if (*cap_img && __this && __this->cap_buf) {
*cap_img = FALSE;
flen = __this->cap_buf;
memcpy(__this->cap_buf + 4, buf, len);
*flen = len;
}
return 0;
}
static int net_video_rec_take_photo(void (*callback)(char *buffer, int len))
{
struct server *server = NULL;
union video_req req = {0};
char *path;
char buf[48];
char name_buf[20];
int err;
if (!(__this_net->net_state == VIDREC_STA_START || __this_net->net_state_ch2 == VIDREC_STA_START)) {
printf("waring :net video not open or video record running \n");
goto error;
}
server = __this_net->net_video_rec;
req.icap.quality = VIDEO_MID_Q;
req.icap.buf_size = CAP_IMG_SIZE;
req.icap.buf = malloc(CAP_IMG_SIZE);
if (!req.icap.buf) {
goto error;
}
req.rec.text_osd = NULL;
req.rec.graph_osd = NULL;
req.icap.text_label = NULL;
req.icap.file_name = name_buf;
req.icap.path = CAMERA0_CAP_PATH"IMG_****.jpg";
path = CAMERA0_CAP_PATH;
err = server_request(server, VIDEO_REQ_IMAGE_CAPTURE, &req);
if (err != 0) {
puts("\n\n\ntake photo err\n\n\n");
goto error;
}
sprintf(buf, "%s%s", path, req.icap.file_name);
printf("%s\n\n", buf);
CTP_CMD_COMBINED(NULL, CTP_REQUEST, "PHOTO_CTRL", "NOTIFY", CTP_REQUEST_MSG);
if (req.icap.buf) {
free(req.icap.buf);
}
return 0;
error:
if (req.icap.buf) {
free(req.icap.buf);
}
return -EINVAL;
}
extern int atoi(const char *);
static void rt_stream_cmd_analysis(u8 chl, u32 add)
{
char *key;
char *value;
struct rt_stream_app_info *info = (struct rt_stream_app_info *)add;
info->width = CONFIG_VIDEO_IMAGE_W;
info->height = CONFIG_VIDEO_IMAGE_H;
__this_net->net_videoreq[chl].rec.width = info->width;
__this_net->net_videoreq[chl].rec.height = info->height;
__this_net->net_videoreq[chl].rec.format = info->type - NET_VIDEO_FMT_AVI;
__this_net->net_videoreq[chl].rec.format = 0;
__this_net->net_videoreq[chl].rec.fps = net_video_rec_get_fps();
__this_net->net_videoreq[chl].rec.real_fps = net_video_rec_get_fps();
__this_net->priv = info->priv;
printf(">>>>>>>> ch %d , info->type : %d ,w:%d , h:%d\n\n", chl, info->type, info->width, info->height);
}
static void net_video_rec_set_bitrate(unsigned int bits_rate)
{
union video_req req = {0};
req.rec.channel = __this_net->channel;
req.rec.state = VIDEO_STATE_RESET_BITS_RATE;
req.rec.abr_kbps = bits_rate;
server_request(__this_net->net_video_rec, VIDEO_REQ_REC, &req);
}
/*
*双路应用层使用小内存YUV大小:根据传参的width可知是实时流或录像分辨率的宽进行区分
*返回值:设定双路的YUV大小(默认200K左右,最小为16行对应YUV大小)(0:1帧对应YUV大小)
*/
u32 app_jpeg_spec_set_large_image_yuv_size(u16 width)
{
#ifdef CONFIG_VIDEO_SPEC_DOUBLE_REC_MODE
return (__SDRAM_SIZE__ > 2 * 1024 * 1024) ? 0 : 200 * 1024;
#endif
return 0;
}
/*双路应用层动态码率修改:根据传参的width可知是实时流或录像分辨率的宽进行区分
返回值:动态码率设置值(0:原始请求设置的码率)
*/
u32 app_jpeg_spec_abr_set(u16 width, u32 fps, u32 abr_kbps)
{
return 0;
}
/*单路应用层动态码率修改:根据传参的width可知是实时流或录像分辨率的宽进行区分
返回值:动态码率设置值(0:原始请求设置的码率)
*/
u32 app_jpeg_abr_set(u16 width, u32 fps, u32 abr_kbps)
{
return 0;
}
/*码率控制,根据具体分辨率设置*/
static int net_video_rec_get_abr(u32 width)
{
/*视频码率kbps使用说明:
码率:一帧图片以K字节为单位大小 * 帧率 * 8,比如:一帧图片为30KB,帧率为20帧,则码率为30*20*8=4800
VGA图片大小说明:低等质量(小于20K),中等质量(20K-40K),高质量(大于40K,极限70K)
720P图片大小说明:低等质量(小于50K),中等质量(50k-100K),高质量(大于100K,极限150K)
*/
if (width <= 640) {
return 3000;
} else {
return 4000;
}
}
static void net_rec_dev_server_event_handler(void *priv, int argc, int *argv)
{
int mark = 2;
struct intent it;
/*
*该回调函数会在录像过程中,写卡出错被当前录像APP调用,例如录像过程中突然拔卡
*/
switch (argv[0]) {
case VIDEO_SERVER_UVM_ERR:
log_e("APP_UVM_DEAL_ERR\n");
break;
case VIDEO_SERVER_PKG_ERR:
log_e("video_server_pkg_err\n");
break;
case VIDEO_SERVER_PKG_END:
if (db_select("cyc") > 0) {
/*video_rec_savefile((int)priv);*/
} else {
net_video_rec_control(0);
}
break;
case VIDEO_SERVER_PKG_NET_ERR:
init_intent(&it);
it.data = &mark;
if (__this_net->net_video0_vrt_on) {
net_rt_video0_stop(&it);
__this_net->is_open = FALSE;
} else if (__this_net->net_video1_vrt_on) {
#ifdef CONFIG_SPI_VIDEO_ENABLE
extern int spi_video_task_kill(void *priv);
int err = spi_video_task_kill(__this_net->priv);
if (!err) {
__this_net->net_video1_vrt_on = 0;
}
#endif
}
break;
default :
break;
}
}
static int net_video_rec0_start()
{
int err;
union video_req req = {0};
struct video_text_osd text_osd = {0};
struct video_graph_osd graph_osd;
u16 max_one_line_strnum;
char buf[128];
#if NET_VIDEO_SHARE_CHANNEL
if (__this && __this->state == VIDREC_STA_START) {
#if (!defined CONFIG_NO_SDRAM_ENABLE)
net_video_rec_free_buf();//使用sdram共用通道释放内存以节省内存,不带sdram则录像和实时流已共用
#endif
union video_req req = {0};
u8 path[48];
__this_net->net_video_rec = __this->video_rec0;
req.rec.packet_cb = stream_packet_cb;
err = server_request(__this_net->net_video_rec, VIDEO_REQ_SET_PACKET_CALLBACK, &req);
if (err) {
return err;
}
struct sockaddr_in *addr = ctp_srv_get_cli_addr(__this_net->priv);
if (!addr) {
addr = cdp_srv_get_cli_addr(__this_net->priv);
}
if (!addr) {
sprintf(path, "usr://%s", "192.168.1.");
} else {
#if (defined CONFIG_NET_UDP_ENABLE)
sprintf(path, "udp://%s:%d", inet_ntoa(addr->sin_addr.s_addr), _FORWARD_PORT);
#elif (defined CONFIG_NET_TCP_ENABLE)
sprintf(path, "tcp://%s:%d", inet_ntoa(addr->sin_addr.s_addr), _FORWARD_PORT);
#elif (defined CONFIG_USR_VIDEO_ENABLE)
sprintf(path, "usr://%s", CONFIG_USR_PATH);
#elif (defined CONFIG_NET_TUTK_ENABLE)
sprintf(req.rec.net_par.netpath, "tutk://%s", " 192.168.1.1");
#endif
}
err = stream_protocol_task_create(path, NULL);
if (!err) {
__this_net->net_state = VIDREC_STA_START;
} else {
__this_net->net_state = VIDREC_STA_STOP;
}
return err;
}
#endif
if (!__this_net->net_video_rec) {
#ifdef CONFIG_UVC_VIDEO2_ENABLE
__this_net->net_video_rec = server_open("video_server", "video2.1");
#else
__this_net->net_video_rec = server_open("video_server", "video0.1");
#endif
if (!__this_net->net_video_rec) {
return VREC_ERR_V0_SERVER_OPEN;
}
server_register_event_handler(__this_net->net_video_rec, (void *)0, net_rec_dev_server_event_handler);
}
__this_net->video_id = 0;
#ifdef CONFIG_UVC_VIDEO2_ENABLE
req.rec.uvc_id = __this_net->uvc_id;
#endif
#ifdef CONFIG_VIDEO_REC_PPBUF_MODE
req.rec.bfmode = VIDEO_PPBUF_MODE;
#endif
#ifdef CONFIG_VIDEO_SPEC_DOUBLE_REC_MODE
req.rec.wl80_spec_mode = VIDEO_WL80_SPEC_DOUBLE_REC_MODE;
#endif
#ifdef CONFIG_UI_ENABLE
req.rec.picture_mode = 1;//整帧图片模式
#endif
#if USE_STATIC_BUFF
req.rec.isc_sbuf = net_isc_sbuf;
req.rec.sbuf_size = NET_ISC_SBUF_SIZE;
#else
req.rec.isc_sbuf = NULL;
req.rec.sbuf_size = 0;
#endif
req.rec.block_done_cb = NULL;
req.rec.camera_type = VIDEO_CAMERA_NORMAL;
req.rec.channel = __this_net->channel = 1;
req.rec.width = __this_net->net_videoreq[0].rec.width;
req.rec.height = __this_net->net_videoreq[0].rec.height;
printf(">>>>>>width=%d height=%d\n\n\n\n", __this_net->net_videoreq[0].rec.width, __this_net->net_videoreq[0].rec.height);
req.rec.state = VIDEO_STATE_START;
req.rec.fpath = CONFIG_REC_PATH_0;
if (__this_net->net_videoreq[0].rec.format == 1) {
puts("in h264\n\n");
req.rec.format = NET_VIDEO_FMT_MOV;
} else {
req.rec.format = NET_VIDEO_FMT_AVI;
}
if (__this_net->net_videoreq[0].rec.format == 1) {
req.rec.fname = "vid_***.mov";
} else {
req.rec.fname = "vid_***.avi";
}
req.rec.quality = VIDEO_LOW_Q;
req.rec.fps = 0;
req.rec.real_fps = net_video_rec_get_fps();
req.rec.net_par.net_audrt_onoff = __this_net->net_video0_art_on;
req.rec.net_par.net_vidrt_onoff = __this_net->net_video0_vrt_on;
req.rec.audio.sample_rate = VIDEO_REC_AUDIO_SAMPLE_RATE;
req.rec.audio.channel = 1;
req.rec.audio.channel_bit_map = 0;
req.rec.audio.volume = AUDIO_VOLUME;
req.rec.audio.buf = __this_net->audio_buf;
req.rec.audio.buf_len = NET_AUDIO_BUF_SIZE;
req.rec.pkg_mute.aud_mute = !db_select("mic");
/*
*码率,I帧和P帧比例,必须是偶数(当录MOV的时候才有效),
*roio_xy :值表示宏块坐标, [6:0]左边x坐标 ,[14:8]右边x坐标,[22:16]上边y坐标,[30:24]下边y坐标,写0表示1个宏块有效
* roio_ratio : 区域比例系数
*/
req.rec.abr_kbps = net_video_rec_get_abr(req.rec.width);
req.rec.IP_interval = 0;
/*感兴趣区域为下方 中间 2/6 * 4/6 区域,可以调整
感兴趣区域qp 为其他区域的 70% ,可以调整
*/
req.rec.roi.roio_xy = (req.rec.height * 5 / 6 / 16) << 24 | (req.rec.height * 3 / 6 / 16) << 16 | (req.rec.width * 5 / 6 / 16) << 8 | (req.rec.width) * 1 / 6 / 16;
req.rec.roi.roi1_xy = (req.rec.height * 11 / 12 / 16) << 24 | (req.rec.height * 4 / 12 / 16) << 16 | (req.rec.width * 11 / 12 / 16) << 8 | (req.rec.width) * 1 / 12 / 16;
req.rec.roi.roi2_xy = 0;
req.rec.roi.roi3_xy = (1 << 24) | (0 << 16) | ((req.rec.width / 16) << 8) | 0;
req.rec.roi.roio_ratio = 256 * 70 / 100 ;
req.rec.roi.roio_ratio1 = 256 * 90 / 100;
req.rec.roi.roio_ratio2 = 0;
req.rec.roi.roio_ratio3 = 256 * 80 / 100;
#ifdef CONFIG_OSD_ENABLE
text_osd.font_w = OSD_DEFAULT_WIDTH;//必须16对齐
text_osd.font_h = OSD_DEFAULT_HEIGHT;//必须16对齐
text_osd.text_format = net_osd_format_buf;
text_osd.x = (req.rec.width - text_osd.font_w * strlen(text_osd.text_format) + 15) / 16 * 16;
text_osd.y = (req.rec.height - text_osd.font_h + 15) / 16 * 16;
text_osd.osd_yuv = 0xe20095;
text_osd.font_matrix_table = NULL;
text_osd.font_matrix_base = NULL;
text_osd.font_matrix_len = 0;
if (db_select("dat") > 0) {
req.rec.text_osd = &text_osd;
}
#endif
/*
*慢动作倍数(与延时摄影互斥,无音频); 延时录像的间隔ms(与慢动作互斥,无音频)
*/
req.rec.slow_motion = 0;
req.rec.tlp_time = 0;//db_select("gap");
req.rec.buf = __this_net->net_v0_fbuf;
req.rec.buf_len = NET_VREC0_FBUF_SIZE;
struct sockaddr_in *addr = ctp_srv_get_cli_addr(__this_net->priv);
if (!addr) {
addr = cdp_srv_get_cli_addr(__this_net->priv);
}
#if (defined CONFIG_NET_UDP_ENABLE)
sprintf(req.rec.net_par.netpath, "udp://%s:%d"
, inet_ntoa(addr->sin_addr.s_addr)
, _FORWARD_PORT);
#elif (defined CONFIG_NET_TCP_ENABLE)
sprintf(req.rec.net_par.netpath, "tcp://%s:%d"
, inet_ntoa(addr->sin_addr.s_addr)
, _FORWARD_PORT);
#elif (defined CONFIG_UVC_VIDEO2_ENABLE)
sprintf(req.rec.net_par.netpath, "usr://%s", "192.168.1.1");
#elif (defined CONFIG_USR_VIDEO_ENABLE)
sprintf(req.rec.net_par.netpath, "usr://%s", CONFIG_USR_PATH);
#elif (defined CONFIG_NET_TUTK_ENABLE)
sprintf(req.rec.net_par.netpath, "tutk://%s", " 192.168.1.1");
#endif
err = server_request(__this_net->net_video_rec, VIDEO_REQ_REC, &req);
if (err != 0) {
puts("\n\n\nstart rec err\n\n\n");
return VREC_ERR_V0_REQ_START;
}
return 0;
}
static int net_video_rec0_stop(u8 close)
{
union video_req req = {0};
int err = 0;
printf("\nnet video rec0 stop\n");
__this_net->net_state = VIDREC_STA_STOPING;
#if NET_VIDEO_SHARE_CHANNEL
if (__this && __this->state == VIDREC_STA_START) {
err = stream_protocol_task_kill();
__this_net->net_video_rec = NULL;
} else
#endif
{
req.rec.channel = 1;
req.rec.state = VIDEO_STATE_STOP;
err = server_request(__this_net->net_video_rec, VIDEO_REQ_REC, &req);
if (err != 0) {
printf("\nstop rec err 0x%x\n", err);
return VREC_ERR_V0_REQ_STOP;
}
if (close) {
if (__this_net->net_video_rec) {
server_close(__this_net->net_video_rec);
__this_net->net_video_rec = NULL;
}
}
}
__this_net->net_state = VIDREC_STA_STOP;
__this_net->video_id = 0;
return 0;
}
static void net_video_rec_free_buf(void)
{
#if (USE_STATIC_BUFF == 0)
if (__this_net->net_v0_fbuf) {
free(__this_net->net_v0_fbuf);
__this_net->net_v0_fbuf = NULL;
}
if (__this_net->audio_buf) {
free(__this_net->audio_buf);
__this_net->audio_buf = NULL;
}
#else
__this_net->net_v0_fbuf = NULL;
__this_net->audio_buf = NULL;
#endif
}
static int net_video_rec_alloc_buf(void)
{
if (!__this_net->net_v0_fbuf && NET_VREC0_FBUF_SIZE) {
#if (USE_STATIC_BUFF == 0)
__this_net->net_v0_fbuf = malloc(NET_VREC0_FBUF_SIZE);
#else
__this_net->net_v0_fbuf = net_video_buf;
#endif
if (!__this_net->net_v0_fbuf) {
puts("malloc v0_buf err\n\n");
return -ENOMEM;
}
}
if (!__this_net->audio_buf && VIDEO_REC_AUDIO_SAMPLE_RATE && NET_AUDIO_BUF_SIZE) {
#if (USE_STATIC_BUFF == 0)
__this_net->audio_buf = malloc(NET_AUDIO_BUF_SIZE);
#else
__this_net->audio_buf = net_audio_buf;
#endif
if (!__this_net->audio_buf) {
free(__this_net->net_v0_fbuf);
__this_net->net_v0_fbuf = NULL;
return -ENOMEM;
}
}
return 0;
}
char *get_net_video_isc_buf(int *buf_size)
{
#if (USE_STATIC_BUFF == 0)
*buf_size = 0;
return 0;
#else
*buf_size = NET_ISC_SBUF_SIZE;
return net_isc_sbuf;
#endif
}
char *get_net_video_rec0_video_buf(int *buf_size)
{
*buf_size = NET_VREC0_FBUF_SIZE;
#if (USE_STATIC_BUFF == 0)
return __this_net->net_v0_fbuf;
#else
return net_video_buf;
#endif
}
char *get_net_video_rec1_video_buf(int *buf_size)
{
*buf_size = 0;
return NULL;
}
char *get_net_video_rec2_video_buf(int *buf_size)
{
*buf_size = 0;
return NULL;
}
char *get_net_video_rec_audio_buf(int *buf_size)
{
*buf_size = NET_AUDIO_BUF_SIZE;
#if (USE_STATIC_BUFF == 0)
return __this_net->audio_buf;
#else
return net_audio_buf;
#endif
}
static int net_video0_rec_start(struct intent *it)
{
int err = 0;
#ifdef CONFIG_VIDEO0_ENABLE
err = net_video_rec_alloc_buf();
if (err) {
return err;
}
if (__this_net->net_video0_art_on || __this_net->net_video0_vrt_on) {
__this_net->net_state = VIDREC_STA_STARTING;
err = net_video_rec0_start();
if (err) {
goto __start_err0;
}
__this_net->net_state = VIDREC_STA_START;
}
return 0;
__start_err0:
puts("\nstart0 err\n");
net_video_rec0_stop(0);
if (err) {
printf("\nstart wrong0 %x\n", err);
//while(1);
}
#endif
return err;
}
static int net_video_rec_start(u8 mark)
{
int err;
if (!__this_net->is_open) {
return 0;
}
puts("start net rec\n");
err = net_video_rec_alloc_buf();
if (err) {
return err;
}
#ifdef CONFIG_VIDEO0_ENABLE
printf("\n art %d, vrt %d\n", __this_net->net_video0_art_on, __this_net->net_video0_vrt_on);
if ((__this_net->net_video0_art_on || __this_net->net_video0_vrt_on)
&& (__this_net->net_state != VIDREC_STA_START)) {
puts("\nnet video rec0 start \n");
err = net_video_rec0_start();
if (err) {
goto __start_err0;
}
__this_net->net_state = VIDREC_STA_START;
}
#endif
return 0;
#ifdef CONFIG_VIDEO0_ENABLE
__start_err0:
puts("\nstart0 err\n");
net_video_rec0_stop(0);
if (err) {
printf("\nstart wrong0 %x\n", err);
}
#endif
return -EFAULT;
}
static int net_video0_rec_stop(u8 close)
{
int err;
#ifdef CONFIG_VIDEO0_ENABLE
__this_net->net_state = VIDREC_STA_STOPING;
err = net_video_rec0_stop(close);
if (err) {
puts("\n net stop0 err\n");
}
__this_net->net_state = VIDREC_STA_STOP;
#endif
return err;
}
static int net_video_rec_stop(u8 close)
{
if (!__this_net->is_open) {
return 0;
}
int err = 0;
#ifdef CONFIG_VIDEO0_ENABLE
puts("\n net_video_rec_stop. 0.. \n");
if (__this_net->net_state == VIDREC_STA_START) {
__this_net->net_state = VIDREC_STA_STOPING;
err = net_video_rec0_stop(close);
if (err) {
puts("\n net stop0 err\n");
}
__this_net->net_state = VIDREC_STA_STOP;
printf("-----%s state stop \n", __func__);
}
#endif
return err;
}
static int net_rt_video0_open(struct intent *it)
{
int ret;
if (!__this_net->is_open) {
return 0;
}
puts("\nnet rt video0 open \n");
#ifdef CONFIG_VIDEO0_ENABLE
if (it) {
u8 mark = *((u8 *)it->data);
if (mark == 0) {
__this_net->net_video0_art_on = 1;
__this_net->net_video0_vrt_on = 0 ;
} else if (mark == 1) {
__this_net->net_video0_vrt_on = 1;
__this_net->net_video0_art_on = 0;
} else {
__this_net->net_video0_art_on = 1;
__this_net->net_video0_vrt_on = 1;
}
rt_stream_cmd_analysis(0, it->exdata);
} else {
if (__this_net->net_video0_art_on == 0 && __this_net->net_video0_vrt_on == 0) {
puts("\n rt not open\n");
return 0;
}
}
if (__this_net->net_state == VIDREC_STA_START) {
puts("\n net rt is on \n");
return 0;
}
ret = net_video0_rec_start(it);
return ret;
#else
return 0;
#endif
}
static int net_rt_video0_stop(struct intent *it)
{
int ret = 0;
puts("\nnet rt video0 stop \n");
if (!__this_net->is_open) {
return 0;
}
#ifdef CONFIG_VIDEO0_ENABLE
u8 mark = 2;
if (it) {
mark = *((u8 *)it->data);
}
if (mark == 0) {
__this_net->net_video0_art_on = 0;
} else if (mark == 1) {
__this_net->net_video0_vrt_on = 0;
} else {
__this_net->net_video0_art_on = 0;
__this_net->net_video0_vrt_on = 0;
}
if (__this_net->net_state == VIDREC_STA_START) {
ret = net_video0_rec_stop(1);
}
#endif
return ret;
}
void net_video_rec0_close()
{
if (__this_net->net_video_rec) {
server_close(__this_net->net_video_rec);
__this_net->net_video_rec = NULL;
}
}
static int net_video_rec_close()
{
#ifdef CONFIG_VIDEO0_ENABLE
net_video_rec0_close();
#endif
return 0;
}
/*
* 录像app的录像控制入口, 根据当前状态调用相应的函数
*/
static int net_video_rec_control(void *_run_cmd)
{
int err = 0;
u32 clust;
int run_cmd = (int)_run_cmd;
struct vfs_partition *part;
if (storage_device_ready() == 0) {
if (!dev_online(SDX_DEV)) {
net_video_rec_post_msg("noCard");
} else {
net_video_rec_post_msg("fsErr");
}
CTP_CMD_COMBINED(NULL, CTP_SDCARD, "VIDEO_CTRL", "NOTIFY", CTP_SDCARD_MSG);
return 0;
} else {
net_video_handler_init();
part = fget_partition(CONFIG_ROOT_PATH);
if (!part) {
printf("err in fget_partition");
return 0;
}
if (__this) {
__this->total_size = part->total_size;
}
#ifdef CONFIG_JLFAT_ENABLE
if (part->clust_size < 32 * 1024 || (part->fs_attr & F_ATTR_RO)) {
#else
if (part->clust_size < 32 || (part->fs_attr & F_ATTR_RO)) {
#endif
net_video_rec_post_msg("fsErr");
CTP_CMD_COMBINED(NULL, CTP_SDCARD, "VIDEO_CTRL", "NOTIFY", CTP_SDCARD_MSG);
return 0;
}
}
if (__this) {
switch (__this->state) {
case VIDREC_STA_IDLE:
case VIDREC_STA_STOP:
if (run_cmd) {
break;
}
__this_net->video_rec_err = FALSE;//用在录像IMC打不开情况下
printf("--NET_VIDEO_START\n");
/*NET_VIDEO_ERR(strm_video_rec_close(1));*/
NET_VIDEO_ERR(net_video_rec_stop(1));
__this_net->fbuf_fcnt = 0;
__this_net->fbuf_ffil = 0;
err = video_rec_control_start();
if (err == 0) {
/* net_video_rec_post_msg("onREC"); */
if (__this->gsen_lock == 1) {
net_video_rec_post_msg("lockREC");
}
}
NET_VIDEO_ERR(err);
/*NET_VIDEO_ERR(strm_video_rec_open());*/
NET_VIDEO_ERR(net_rt_video0_open(NULL));
/*NET_VIDEO_ERR(net_rt_video1_open(NULL));*/
net_video_rec_status_notify();
printf("--NET_VIDEO_OPEN OK\n");
break;
case VIDREC_STA_START:
if (run_cmd == 0) {
printf("--NET_VIDEO_STOP\n");
/*NET_VIDEO_ERR(strm_video_rec_close(1));*/
NET_VIDEO_ERR(net_video_rec_stop(1));
__this_net->fbuf_fcnt = 0;
__this_net->fbuf_ffil = 0;
err = video_rec_control_doing();
NET_VIDEO_ERR(err);
/*NET_VIDEO_ERR(strm_video_rec_open());*/
NET_VIDEO_ERR(net_video_rec_start(1));
printf("--NET_VIDEO_OPEN OK\n");
}
net_video_rec_status_notify();
break;
default:
puts("\nvrec forbid\n");
err = 1;
break;
}
}
return err;
}
/*
*录像的状态机,进入录像app后就是跑这里
*/
static int net_video_rec_state_machine(struct application *app, enum app_state state, struct intent *it)
{
int err = 0;
int len;
char buf[128];
switch (state) {
case APP_STA_START:
if (!it) {
break;
}
switch (it->action) {
case ACTION_VIDEO_REC_MAIN:
net_video_server_init();
break;
case ACTION_VIDEO_TAKE_PHOTO:
/*printf("----ACTION_VIDEO_TAKE_PHOTO----\n\n");*/
net_video_rec_take_photo(NULL);
break;
case ACTION_VIDEO_REC_CONCTRL:
printf("----ACTION_VIDEO_REC_CONCTRL-----\n\n");
err = net_video_rec_control(0);
break;
case ACTION_VIDEO_REC_GET_APP_STATUS:
printf("----ACTION_VIDEO_REC_GET_APP_STATUS-----\n\n");
video_rec_get_app_status(it);
break;
case ACTION_VIDEO_REC_GET_PATH:
/*printf("----ACTION_VIDEO_REC_GET_PATHL-----\n\n");*/
break;
case ACTION_VIDEO0_OPEN_RT_STREAM:
printf("----ACTION_VIDEO0_OPEN_RT_STREAM-----\n\n");
__this_net->is_open = TRUE;
__this_net->fbuf_fcnt = 0;
__this_net->fbuf_ffil = 0;
#ifdef CONFIG_SPI_VIDEO_ENABLE
extern int spi_video_wait_done(void);
spi_video_wait_done();
#endif
err = net_rt_video0_open(it);
sprintf(buf, "format:%d,w:%d,h:%d,fps:%d,rate:%d"
, __this_net->net_videoreq[0].rec.format
, __this_net->net_videoreq[0].rec.width
, __this_net->net_videoreq[0].rec.height
, __this_net->net_videoreq[0].rec.real_fps
, VIDEO_REC_AUDIO_SAMPLE_RATE);
printf("<<<<<<< : %s\n\n\n\n\n", buf);
if (err) {
printf("ACTION_VIDEO0_OPEN_RT_STREAM err!!!\n\n");
CTP_CMD_COMBINED(NULL, CTP_RT_OPEN_FAIL, "OPEN_RT_STREAM", "NOTIFY", CTP_RT_OPEN_FAIL_MSG);
} else {
if (CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "OPEN_RT_STREAM", "NOTIFY", buf)) {
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "OPEN_RT_STREAM", "NOTIFY", buf);
}
printf("CTP NOTIFY VIDEO0 OK\n\n");
}
break;
case ACTION_VIDEO1_OPEN_RT_STREAM:
printf("----ACTION_VIDEO1_OPEN_RT_STREAM----\n\n");
__this_net->fbuf_fcnt = 0;
__this_net->fbuf_ffil = 0;
#ifdef CONFIG_SPI_VIDEO_ENABLE
extern int spi_video_task_create(void *priv);
extern int spi_camera_width_get(void);
extern int spi_camera_height_get(void);
extern int spi_video_wait_done(void);
spi_video_wait_done();
if (it) {
rt_stream_cmd_analysis(1, it->exdata);
err = spi_video_task_create(__this_net->priv);
if (!err) {
__this_net->net_video1_vrt_on = 1;
__this_net->net_videoreq[1].rec.width = spi_camera_width_get();
__this_net->net_videoreq[1].rec.height = spi_camera_height_get();
__this_net->net_videoreq[1].rec.real_fps = 15;
}
}
#endif
sprintf(buf, "format:%d,w:%d,h:%d,fps:%d,rate:%d"
, __this_net->net_videoreq[1].rec.format
, __this_net->net_videoreq[1].rec.width
, __this_net->net_videoreq[1].rec.height
, __this_net->net_videoreq[1].rec.real_fps
, VIDEO_REC_AUDIO_SAMPLE_RATE);
printf("<<<<<<< : %s\n\n\n\n\n", buf);
if (err) {
printf("ACTION_VIDEO1_OPEN_RT_STREAM err!!!\n\n");
CTP_CMD_COMBINED(NULL, CTP_RT_OPEN_FAIL, "OPEN_PULL_RT_STREAM", "NOTIFY", CTP_RT_OPEN_FAIL_MSG);
} else {
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "OPEN_PULL_RT_STREAM", "NOTIFY", buf);
printf("CTP NOTIFY VIDEO1 OK\n\n");
}
break;
case ACTION_VIDEO0_CLOSE_RT_STREAM:
printf("---ACTION_VIDEO0_CLOSE_RT_STREAM---\n\n");
#ifdef CONFIG_SPI_VIDEO_ENABLE
extern int spi_video_wait_done(void);
spi_video_wait_done();
#endif
net_rt_video0_stop(it);
if (err) {
printf("ACTION_VIDEO_CLOE_RT_STREAM err!!!\n\n");
strcpy(buf, "status:0");
} else {
strcpy(buf, "status:1");
}
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "CLOSE_RT_STREAM", "NOTIFY", buf);
printf("CTP NOTIFY VIDEO0 OK\n\n");
__this_net->is_open = FALSE;
__this_net->fbuf_fcnt = 0;
__this_net->fbuf_ffil = 0;
break;
case ACTION_VIDEO1_CLOSE_RT_STREAM:
printf("---ACTION_VIDEO1_CLOSE_RT_STREAM---\n\n");
#ifdef CONFIG_SPI_VIDEO_ENABLE
extern int spi_video_task_kill(void *priv);
extern int spi_video_wait_done(void);
spi_video_wait_done();
err = spi_video_task_kill(__this_net->priv);
if (!err) {
__this_net->net_video1_vrt_on = 0;
}
#endif
if (err) {
printf("ACTION_VIDE1_CLOE_RT_STREAM err!!!\n\n");
strcpy(buf, "status:0");
} else {
strcpy(buf, "status:1");
}
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "CLOSE_PULL_RT_STREAM", "NOTIFY", buf);
printf("CTP NOTIFY VIDEO1 OK\n\n");
__this_net->is_open = FALSE;
__this_net->fbuf_fcnt = 0;
__this_net->fbuf_ffil = 0;
break;
case ACTION_VIDEO_CYC_SAVEFILE:
#if 0
video_cyc_file(0);
#if defined CONFIG_VIDEO1_ENABLE
video_cyc_file(1);
#endif
#if defined CONFIG_VIDEO2_ENABLE
video_cyc_file(2);
#endif
#endif
strcpy(buf, "status:1");
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "VIDEO_CYC_SAVEFILE", "NOTIFY", buf);
break;
}
break;
}
return err;
}
static void net_video_rec_ioctl(u32 argv)
{
char buf[128];
u32 *pargv = (u32 *)argv;
u32 type = (u32)pargv[0];
char *path = (char *)pargv[1];
/*printf("%s type : %d , %s \n\n", __func__, type, path);*/
switch (type) {
case NET_VIDREC_STA_STOP:
if (__this_net->net_state == VIDREC_STA_START || __this_net->net_state1 == VIDREC_STA_START \
|| __this_net->net_state_ch2 == VIDREC_STA_START || __this_net->net_state1_ch2 == VIDREC_STA_START) {
net_video_rec_stop(1);
}
/*if (__this_strm->state == VIDREC_STA_START || __this_strm->state_ch2 == VIDREC_STA_START) {*/
/*strm_video_rec_close(1);*/
/*}*/
__this_net->is_open = FALSE;
net_video_rec_free_buf();
break;
case NET_VIDREC_STATE_NOTIFY:
sprintf(buf, "status:%d", ((__this->state == VIDREC_STA_START) ? 1 : 0));
CTP_CMD_COMBINED(__this_net->priv, CTP_NO_ERR, "VIDEO_CTRL", "NOTIFY", buf);
break;
default :
return ;
}
}
static int net_video_rec_device_event_handler(struct device_event *dev)
{
int err;
struct intent it;
u8 *tpye;
if (!ASCII_StrCmp(dev->arg, "usb_host*", 9)) {
switch (dev->event) {
case DEVICE_EVENT_IN:
tpye = (u8 *)dev->value;
if (strstr(tpye, "uvc")) {
__this_net->uvc_id = tpye[3] - '0';
}
printf("UVC or msd_storage online %s, id=%d\n", tpye, __this_net->uvc_id);
break;
case DEVICE_EVENT_OUT:
tpye = (u8 *)dev->value;
if (strstr(tpye, "uvc")) {
__this_net->uvc_id = tpye[3] - '0';
}
printf("UVC or msd_storage offline %s, id=%d\n", tpye, __this_net->uvc_id);
if (__this && __this->state == VIDREC_STA_START) {
video_rec_control_doing();
}
net_video_rec_event_stop();
break;
}
} else if (!ASCII_StrCmp(dev->arg, "sd*", 4)) {
switch (dev->event) {
case DEVICE_EVENT_IN:
/* video_rec_sd_event_ctp_notify(1); */
/* extern int video_rec_sd_in(); */
video_rec_sd_in();
break;
case DEVICE_EVENT_OUT:
/* extern int video_rec_sd_out(); */
video_rec_sd_out();
/* video_rec_sd_event_ctp_notify(0); */
break;
}
} else if (!ASCII_StrCmp(dev->arg, "sys_power", 7)) {
switch (dev->event) {
case DEVICE_EVENT_POWER_CHARGER_IN:
puts("---charger in\n\n");
if ((__this && __this->state == VIDREC_STA_IDLE) ||
(__this && __this->state == VIDREC_STA_STOP)) {
video_rec_control_start();
}
break;
case DEVICE_EVENT_POWER_CHARGER_OUT:
puts("---charger out\n");
if (__this && __this->state == VIDREC_STA_START) {
video_rec_control_doing();
}
break;
}
}
return 0;
}
static int net_video_key_event_handler(struct key_event *key)
{
int ret = 0;
static char state = 1;
switch (key->action) {
case KEY_EVENT_CLICK:
printf("KEY_EVENT_CLICK \n");
int cmd_video_rec_ctl(char start);
cmd_video_rec_ctl(state);
state = !state;
ret = true;
break;
case KEY_EVENT_LONG:
printf("KEY_EVENT_LONG \n");
int cmd_take_photo_ctl(char start);
cmd_take_photo_ctl(1);
ret = true;
break;
default:
break;
}
return ret;
}
int net_video_event_hander(void *e)
{
struct net_event *event = (struct net_event *)e;
struct ctp_arg *event_arg = (struct ctp_arg *)event->arg;
/* struct net_event *net = &event->u.net; */
switch (event->event) {
case NET_EVENT_CMD:
/*printf("IN NET_EVENT_CMD\n\n\n\n");*/
ctp_cmd_analysis(event_arg->topic, event_arg->content, event_arg->cli);
if (event_arg->content) {
free(event_arg->content);
}
event_arg->content = NULL;
if (event_arg) {
free(event_arg);
}
event_arg = NULL;
return true;
break;
case NET_EVENT_DATA:
/* printf("IN NET_EVENT_DATA\n"); */
break;
/* case NET_EVENT_SMP_CFG_FINISH: */
/* printf(">>>>>>>>>>>>>>>>>>NET_EVENT_SMP_CFG_FINISH"); */
/* config_network_stop(); */
/* config_network_connect(); */
/* break; */
}
return false;
}
static void net_video_server_task(void *p)
{
int res;
int msg[16];
if (os_mutex_create(&net_vdrec_mutex) != OS_NO_ERR) {
printf("net_video_server_task , os_mutex_create err !!!\n\n");
return;
}
net_video_handler_init();
printf("net_video_server_task running\n\n");
while (1) {
res = os_task_pend("taskq", msg, ARRAY_SIZE(msg));
if (os_task_del_req(OS_TASK_SELF) == OS_TASK_DEL_REQ) {
os_task_del_res(OS_TASK_SELF);
}
switch (res) {
case OS_TASKQ:
switch (msg[0]) {
case Q_EVENT:
break;
case Q_MSG:
net_video_rec_ioctl((u32)msg[1]);
break;
default:
break;
}
break;
case OS_TIMER:
break;
case OS_TIMEOUT:
break;
}
}
os_mutex_del(&net_vdrec_mutex, OS_DEL_ALWAYS);
}
void net_video_server_init(void)
{
task_create(net_video_server_task, 0, "net_video_server");
}
/*录像app的事件总入口*/
static int net_video_rec_event_handler(struct application *app, struct sys_event *event)
{
switch (event->type) {
case SYS_KEY_EVENT:
return net_video_key_event_handler((struct key_event *)event->payload);
case SYS_DEVICE_EVENT:
return net_video_rec_device_event_handler((struct device_event *)event->payload);
/*return video_rec_device_event_action((struct device_event *)event->payload);//录卡时:设备事件和 vidoe_rec公用一个handler,*/
case SYS_NET_EVENT:
net_video_event_hander((void *)event->payload);
return false;
default:
return false;
}
}
static const struct application_operation net_video_rec_ops = {
.state_machine = net_video_rec_state_machine,
.event_handler = net_video_rec_event_handler,
};
//REGISTER_APPLICATION(app_video_rec) = {
// .name = "net_video_rec",
// .ops = &net_video_rec_ops,
// .state = APP_STA_DESTROY,
//};