doubao_chat/apps/wifi_camera/wifi/user_video_rec2.c

310 lines
9.0 KiB
C
Raw 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 "app_config.h"
#include "asm/debug.h"
#include "asm/osd.h"
#include "asm/isc.h"
#include "app_database.h"
#include "storage_device.h"
#include "server/ctp_server.h"
#include "os/os_api.h"
#include "camera.h"
#include "net_server.h"
#include "server/net_server.h"
#include "stream_protocol.h"
#if 0//def CONFIG_USR_VIDEO_ENABLE
struct user_video_hdl {
u8 state;
u8 page_turning;
u8 req_send;
u8 channel;
u8 *user_isc_buf;
u8 *user_video_buf;
u8 *user_audio_buf;
struct server *user_video_rec;
};
#ifdef CONFIG_VIDEO_720P
#define USER_ISC_SBUF_SIZE (CONFIG_VIDEO_IMAGE_W*64*3/2)
#define USER_VIDEO_SBUF_SIZE (200 * 1024)
#define USER_AUDIO_SBUF_SIZE (32 * 1024)
#define CAP_IMG_SIZE (150*1024)
#define CONFIG_USER_VIDEO_WIDTH 1280
#define CONFIG_USER_VIDEO_HEIGHT 720
#else
#define USER_ISC_SBUF_SIZE (CONFIG_VIDEO_IMAGE_W*32*3/2)
#define USER_VIDEO_SBUF_SIZE (80 * 1024)
#define USER_AUDIO_SBUF_SIZE (32 * 1024)
#define CAP_IMG_SIZE (40*1024)
#define CONFIG_USER_VIDEO_WIDTH 640
#define CONFIG_USER_VIDEO_HEIGHT 480
#endif
#define USER_ISC_STATIC_BUFF_ENABLE 0 //1使用静态内部ram
#define USER_AUDIO_ENABLE 0 //1开启音频需要添加video_rt_usr.c,音视频回调也会回调到video_rt_usr.c
#if USER_ISC_STATIC_BUFF_ENABLE
extern u8 net_isc_sbuf[USER_ISC_SBUF_SIZE];
static u8 *user_isc_sbuf = net_isc_sbuf;
/*static u8 user_isc_sbuf[USER_ISC_SBUF_SIZE] SEC(.sram) ALIGNE(32);//必须32对齐*/
#endif
static const unsigned char user_osd_format_buf[] = "yyyy-nn-dd hh:mm:ss";
extern int uvc_host_online(void);
int user_video_audio_packet_channel0_callback(u8 type, u8 *buf, u32 size)
{
if (type == VIDEO_REC_JPEG_TYPE_VIDEO) {
putchar('V');
} else {
putchar('A');
}
return 0;
}
int user_video_audio_packet_channel1_callback(u8 type, u8 *buf, u32 size)
{
if (type == VIDEO_REC_JPEG_TYPE_VIDEO) {
putchar('V');
} else {
putchar('A');
}
return 0;
}
/*码率控制,根据具体分辨率设置*/
int user_video_rec_get_abr(u32 width)
{
if (width <= 640) {
return 2800;
} else {
return 4000;
}
}
void *user_video_rec0_open(char channel)//channel:0/1,如果开启录像则channel是1
{
int err = 0;
union video_req req = {0};
char path[48];
struct user_video_hdl *user = zalloc(sizeof(struct user_video_hdl));
if (!user) {
printf("user open err \n");
return 0;
}
if (!user->user_video_buf) {
user->user_video_buf = malloc(USER_VIDEO_SBUF_SIZE);
if (!user->user_video_buf) {
puts("no mem \n");
free(user);
return NULL;
}
}
#if USER_AUDIO_ENABLE
if (!user->user_audio_buf) {
user->user_audio_buf = malloc(USER_AUDIO_SBUF_SIZE);
if (!user->user_audio_buf) {
puts("no mem \n");
free(user);
return NULL;
}
}
#endif
#if USER_ISC_STATIC_BUFF_ENABLE
user->user_isc_buf = user_isc_sbuf;
#else
if (!user->user_isc_buf) {
user->user_isc_buf = malloc(USER_ISC_SBUF_SIZE);
if (!user->user_isc_buf) {
puts("no mem \n");
goto __exit;
}
}
#endif
if (!user->user_video_rec) {
char dev_name[32];
user->channel = channel;
#ifdef CONFIG_UVC_VIDEO2_ENABLE
sprintf(dev_name, "video2.%d", user->channel);
user->user_video_rec = server_open("video_server", dev_name);
#else
sprintf(dev_name, "video0.%d", user->channel);
user->user_video_rec = server_open("video_server", dev_name);
#endif
if (!user->user_video_rec) {
goto __exit;
}
}
#ifdef CONFIG_UVC_VIDEO2_ENABLE
req.rec.uvc_id = uvc_host_online();
#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
req.rec.picture_mode = 0;//非绘本模式
req.rec.isc_sbuf = user->user_isc_buf;
req.rec.sbuf_size = USER_ISC_SBUF_SIZE;
req.rec.camera_type = VIDEO_CAMERA_NORMAL;
req.rec.channel = user->channel;
req.rec.width = CONFIG_USER_VIDEO_WIDTH;
req.rec.height = CONFIG_USER_VIDEO_HEIGHT;
req.rec.state = VIDEO_STATE_START;
req.rec.fpath = CONFIG_REC_PATH_0;
#if USER_AUDIO_ENABLE
req.rec.format = NET_VIDEO_FMT_AVI;//支持音视频
#else
req.rec.format = USER_VIDEO_FMT_AVI;//USER_VIDEO_FMT_AVI模式仅支持视频
#endif
req.rec.quality = VIDEO_LOW_Q;//VIDEO_MID_Q;
req.rec.fps = 0;
req.rec.real_fps = 25;//帧率
//需要音频:请写audio.sample_rate和audio.buf、audio.buf_len
#if USER_AUDIO_ENABLE
req.rec.audio.sample_rate = 8000;// 音频采样率
#else
req.rec.audio.sample_rate = 0;//8000 音频采样率
#endif
req.rec.audio.channel = 1;
req.rec.audio.channel_bit_map = 0;
req.rec.audio.volume = 64;//音频增益0-100
req.rec.audio.buf = user->user_audio_buf;//音频BUFF
req.rec.audio.buf_len = USER_AUDIO_SBUF_SIZE;//音频BUFF长度
req.rec.abr_kbps = user_video_rec_get_abr(req.rec.width);//JPEG图片码率
req.rec.buf = user->user_video_buf;
req.rec.buf_len = USER_VIDEO_SBUF_SIZE;
req.rec.block_done_cb = 0;//user_yuv420_block_scan;//设置YUV420中断回调函数
#ifdef CONFIG_OSD_ENABLE
struct video_text_osd text_osd = {0};
text_osd.font_w = OSD_DEFAULT_WIDTH;//必须16对齐
text_osd.font_h = OSD_DEFAULT_HEIGHT;//必须16对齐
text_osd.text_format = user_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;
req.rec.text_osd = &text_osd;
#endif
sprintf(path, "usr://%s", "user_path");
strcpy(req.rec.net_par.netpath, path);
err = server_request(user->user_video_rec, VIDEO_REQ_REC, &req);
if (err != 0) {
puts("user start rec err\n");
goto __exit;
}
req.rec.packet_cb = user->channel ? user_video_audio_packet_channel1_callback : user_video_audio_packet_channel0_callback;//注册数据包回调函数进行协议转发
err = server_request(user->user_video_rec, VIDEO_REQ_SET_PACKET_CALLBACK, &req);
if (err != 0) {
puts("stream_packet_cb set err\n");
goto __exit;
}
user->state = true;
printf("user video rec open ok\n");
return user;
__exit:
if (user->user_video_rec) {
memset(&req, 0, sizeof(req));
req.rec.channel = user->channel;
req.rec.state = VIDEO_STATE_STOP;
server_request(user->user_video_rec, VIDEO_REQ_REC, &req);
server_close(user->user_video_rec);
user->user_video_rec = NULL;
}
if (user->user_video_buf) {
free(user->user_video_buf);
user->user_video_buf = NULL;
}
#if !USER_ISC_STATIC_BUFF_ENABLE
if (user->user_isc_buf) {
free(user->user_isc_buf);
user->user_isc_buf = NULL;
}
#endif
free(user);
return NULL;
}
int user_video_rec0_close(void *p_user)
{
int err = 0;
struct user_video_hdl *user = p_user;
union video_req req = {0};
if (!user) {
return -EINVAL;
}
if (user->user_video_rec) {
req.rec.channel = user->channel;
req.rec.state = VIDEO_STATE_STOP;
err = server_request(user->user_video_rec, VIDEO_REQ_REC, &req);
if (err != 0) {
printf("\nstop rec err 0x%x\n", err);
return -EINVAL;
}
server_close(user->user_video_rec);
user->user_video_rec = NULL;
user->state = false;
printf("user video rec close ok\n");
}
if (user->user_video_buf) {
free(user->user_video_buf);
user->user_video_buf = NULL;
}
if (user->user_audio_buf) {
free(user->user_audio_buf);
user->user_audio_buf = NULL;
}
#if !USER_ISC_STATIC_BUFF_ENABLE
if (user->user_isc_buf) {
free(user->user_isc_buf);
user->user_isc_buf = NULL;
}
#endif
free(user);
return 0;
}
#if 0
static void user_video_test1(void)
{
void *user_video0, *user_video1;
int cnt = 0;
#ifdef CONFIG_UVC_VIDEO2_ENABLE
while (uvc_host_online() < 0) {
os_time_dly(100);
}
#endif
printf("~~~~~~~~~~~~~~~~~~~~~~0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
while (1) {
user_video0 = user_video_rec0_open(0);
user_video1 = user_video_rec0_open(1);
cnt = 10;
while (--cnt) {
os_time_dly(100);
puts("close 0");
user_video_rec0_close(user_video1);
puts("open 0");
user_video1 = user_video_rec0_open(1);
}
puts("colse 0");
user_video_rec0_close(user_video0);
puts("colse 1");
user_video_rec0_close(user_video1);
}
}
static void user_video_init(void)
{
thread_fork("user_video", 10, 1500, 64, 0, user_video_test1, NULL);
}
late_initcall(user_video_init);
#endif
#endif