1、同步BR28。add 文件传输crc校验心跳包,防止传输大文件校验超时;

2、修正科大讯飞、摄像头测试问题;
This commit is contained in:
huxi
2025-12-15 14:39:25 +08:00
parent 719f612ab5
commit 48416abdf1
67 changed files with 3512 additions and 2958 deletions
@@ -61,7 +61,7 @@ struct auth_info_t {
struct tm pt;
};
extern void ntp_client_get_time(const char *host);
extern int ntp_client_get_time(const char *host);
extern size_t strftime_2(char *ptr, size_t maxsize, const char *format, const struct tm *timeptr);
/* void *_calloc_r(struct _reent *r, size_t a, size_t b) */
@@ -134,12 +134,11 @@ char *ifly_authentication(char *host_name, char *host, char *path, int retry)
__retry:
//获取网络时间
/* ntp_client_get_time("s2c.time.edu.cn"); */
ntp_client_get_time("ntp.ntsc.ac.cn");
/* int ntp = ntp_client_get_time("s2c.time.edu.cn"); */
/* if (ntp == -1) { */
/* log_error("get ntp error!!\n"); */
/* return NULL; */
/* } */
int ntp = ntp_client_get_time("s2c.time.edu.cn");
if (ntp == -1) {
log_error("get ntp error!!\n");
return NULL;
}
int week = ifly_get_sys_time(&(auth->curtime));
auth->pt.tm_year = auth->curtime.year - 1900;
auth->pt.tm_mon = auth->curtime.month - 1;
@@ -186,7 +186,7 @@ char *ifly_tts_format_text_data(void)
cJSON *cjson_data = NULL;
char *buf = net_iflytek_malloc(MAX_SPARKDESK_LEN * 4); // 因base64编码比字符串要大,根据需要加大buf
mbedtls_base64_encode((unsigned char *)buf, MAX_SPARKDESK_LEN, (size_t *)&out_len, (unsigned char *)tts_info.param->text_res, strlen(tts_info.param->text_res) + 1);
mbedtls_base64_encode((unsigned char *)buf, MAX_SPARKDESK_LEN * 4, (size_t *)&out_len, (unsigned char *)tts_info.param->text_res, strlen(tts_info.param->text_res) + 1);
//定义最长回答
cjson_test = cJSON_CreateObject();
+11 -1
View File
@@ -178,6 +178,16 @@ static void ifly_vad_recv_cb(u8 *j_str, u32 len, u8 type)
}
vad_info.status = IFLY_VAD_STATUS_RECV;
cJSON *cjson_code = cJSON_GetObjectItem(cjson_root, "code");
if (cjson_code && cjson_code->valueint != 0) {
log_error("code error...%d\n", cjson_code->valueint);
if (vad_info.status <= IFLY_VAD_STATUS_RECV_END) {
vad_info.status = IFLY_VAD_STATUS_RECV_ERROR;
}
vad_info.param->event_cb(IFLY_VAD_EVT_NETWORK_RECV_ERROR, vad_info.param);
return;
}
cJSON *cjson_data = cJSON_GetObjectItem(cjson_root, "data");
cJSON *cjson_status = cJSON_GetObjectItem(cjson_data, "status");
cJSON *cjson_result = cJSON_GetObjectItem(cjson_data, "result");
@@ -213,7 +223,7 @@ static void ifly_vad_recv_cb(u8 *j_str, u32 len, u8 type)
log_info("final res:%s\n", vad_info.param->vad_res);
if (cjson_status->valueint == STATUS_LAST_FRAME) {
if (cjson_status && cjson_status->valueint == STATUS_LAST_FRAME) {
vad_info.status = IFLY_VAD_STATUS_RECV_END;
vad_info.recv_finish = 1;
vad_info.param->event_cb(IFLY_VAD_EVT_RECV_OK, vad_info.param);
@@ -97,7 +97,31 @@ static void file_transfer_download_file_check_continue(void)
msg[2] = 0;
os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief file_transfer_verify_heartbeat_packet 心跳包
*/
/* ------------------------------------------------------------------------------------*/
static void file_transfer_verify_heartbeat_packet(void)
{
// 每1M发送一次心跳包,保证不会因为校验时间过长触发超时
static u8 heartbeat_cnt = 0;
if (ftp_d) {
if (ftp_d->start_timerout) {
sys_timer_re_run(ftp_d->start_timerout);
}
u8 cur_cnt = (ftp_d->check.counter * sizeof(ftp_d->win)) / (1 * 1024 * 1024);
u16 len = 0;
u32 offset = 0;
if (heartbeat_cnt != cur_cnt) {
ftp_d->win[0] = 0;
WRITE_BIG_U16(ftp_d->win + 1, len);
WRITE_BIG_U32(ftp_d->win + 3, offset);
JL_CMD_send(JL_OPCODE_FILE_TRANSFER, ftp_d->win, 7, 0, 0, NULL);
heartbeat_cnt = cur_cnt;
}
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件数据块crc校验
@param
@@ -119,6 +143,7 @@ static void __file_transfer_download_file_check_caculate(void *priv)
cnt = ftp_d->check.counter;
}
log_info("cnt = %d, check.counter = %d, crc_tmp = %x\n", cnt, ftp_d->check.counter, ftp_d->check.crc_tmp);
file_transfer_verify_heartbeat_packet();
for (int i = 0; i < cnt; i++) {
fread(ftp_d->win, sizeof(ftp_d->win), 1, ftp_d->file);
ftp_d->check.crc_tmp = CRC16_with_initval(ftp_d->win, sizeof(ftp_d->win), ftp_d->check.crc_tmp);
@@ -193,9 +193,11 @@ void *jl_mbedtls_calloc(unsigned long count, unsigned long size)
#if WEBSOCKET_API_USE_PSRAM
#define WEBSOCKET_API_MALLOC(size) malloc_psram(size)
#define WEBSOCKET_API_REALLOC(ptr, size) realloc_psram(ptr, size)
#define WEBSOCKET_API_FREE(ptr) free_psram(ptr)
#else
#define WEBSOCKET_API_MALLOC(size) malloc(size)
#define WEBSOCKET_API_REALLOC(ptr, size) realloc(ptr, size)
#define WEBSOCKET_API_FREE(ptr) free(ptr)
#endif
@@ -216,6 +218,33 @@ void *websocket_api_malloc(size_t size)
return p;
}
void jl_websocket_api_free(void *pv)
{
if (pv != NULL) {
WEBSOCKET_API_FREE(pv);
pv = NULL;
}
}
void *jl_websocket_api_malloc(size_t size)
{
void *p = WEBSOCKET_API_MALLOC(size);
return p;
}
void *jl_websocket_api_zalloc(size_t size)
{
void *ptr = WEBSOCKET_API_MALLOC(size);
if (ptr) {
memset(ptr, 0, size);
}
return ptr;
}
void *jl_websocket_api_realloc(void *ptr, size_t size)
{
return WEBSOCKET_API_REALLOC(ptr, size);
}
#else
const int CONFIG_LWIP_NET_ENABLE = 0;
#endif
+2 -2
View File
@@ -1,4 +1,4 @@
.section .sys.version, "ax"
.long 313673739
.asciz "-@20251209-$fa0a9cb7"
.long 314161597
.asciz "-@20251215-$2aa6cfb6"
@@ -131,9 +131,7 @@ static int ai_text_rx_cb(u8 ai_text, u8 *data, int len)
memcpy((void *)ai_txt1, data, len);
ai_txt1[len] = '\0';
}
if (ai_text == 2) {
UI_MSG_POST("AI_ERROR");
}
// UTF8
ai_txttempa = tts_txt;
ai_txttempb = ai_txt2;
@@ -705,13 +705,6 @@ static int AI_dial_time_onchange(void *ctr, enum element_change_event e, void *a
return 0;
}
REGISTER_UI_EVENT_HANDLER(AI_DIALOGUE)
.onchange = AI_dialogue_onchange,
.onkey = NULL,
.ontouch = NULL,
};
REGISTER_UI_EVENT_HANDLER(AI_DIALOGUE)
.onchange = AI_dialogue_onchange,
.onkey = NULL,
@@ -692,7 +692,7 @@ REGISTER_UI_EVENT_HANDLER(CAM_CAMERA_TIME_LAYOUT)
//****************************************************************************************//
// 相册
//****************************************************************************************//
void *animig_open(char *name, int window_id, int arg);
/* void *animig_open(char *name, int window_id, int arg); */
/* ------------------------------------------------------------------------------------*/
/**
* @brief cam_photo_list_child_onchange
@@ -1033,14 +1033,17 @@ static int cam_show_layout_onchange1(void *ctrl, enum element_change_event event
struct ui_grid *grid = (struct ui_grid *)ctrl;
struct element *elm = (struct element *)ctrl;
struct draw_context *dc = (struct draw_context *)arg;
AVI_PARAM param;
switch (event) {
case ON_CHANGE_INIT:
if (!__this->sel_path) {
break;
}
if (__this->view_video) {
param.is_dial = 0;
param.is_audio_mute = 0;
set_avi_play_mode(0);
animig_open(__this->sel_path, 0, 3);
animig_open(__this->sel_path, param, 3);
}
break;
case ON_CHANGE_SHOW_POST:
@@ -251,6 +251,8 @@ void cube_effect_init(struct element *curr_elm, struct rect *lcd_rect)
if (__this->init) {
return;
}
__this->init = 1;
struct ui_platform_api *platform_api = ui_get_platform_api();
ASSERT(platform_api);
struct draw_context dc_tmp = {0};
@@ -411,7 +413,7 @@ void cube_effect_init(struct element *curr_elm, struct rect *lcd_rect)
}
__this->dial_page_index = -1;
__this->init = 1;
/* __this->init = 1; */
for (int i = 1; i < 6; i++) {
win = __this->page_id[i];
if (win == DIAL_PAGE_0) {
@@ -519,6 +519,7 @@ void cube_reflection_effect_init(struct element *curr_elm)
return;
}
__this->init = 1;
struct ui_platform_api *platform_api = ui_get_platform_api();
ASSERT(platform_api);
struct draw_context dc_tmp = {0};
@@ -653,7 +654,7 @@ void cube_reflection_effect_init(struct element *curr_elm)
__this->curr_elm = curr_elm;
__this->init = 1;
/* __this->init = 1; */
}
/* ------------------------------------------------------------------------------------*/
@@ -750,6 +750,8 @@ static int watch_dial_bgp_deinit(struct watch_param *param)
}
return 0;
}
extern char *watch_avi_get_related_path(u8 cur_watch);
static int watch_dial_bgp_init(struct watch_param *param)
{
watch_dial_bgp_deinit(param);
@@ -757,19 +759,22 @@ static int watch_dial_bgp_init(struct watch_param *param)
char *bg_path;
u8 watch_mode_type = 0;
#if TCFG_VIDEO_DIAL_ENABLE
AVI_PARAM avi_dial_param;
syscfg_read(CFG_DIAL_TYPE_SEL, (u8 *)&watch_mode_type, 1);
if (watch_mode_type == 1) {
extern char *watch_avi_get_related_path(u8 cur_watch);
bg_path = watch_avi_get_related_path(watch_get_style());
log_debug("cur watch style %d, bgp_path:%s\n\n\n\n\n", watch_get_style(), bg_path);
/* bg_path=NULL; */
if (bg_path) {
animig_open((char *)bg_path, 0, 3); // 缓存3帧可以达到流畅播放30FPS
avi_dial_param.is_dial = 1;
avi_dial_param.is_audio_mute = 0;
set_avi_play_mode(AVI_PLAY_LOOP);
animig_open((char *)bg_path, avi_dial_param, 3); // 缓存3帧可以达到流畅播放30FPS
avi_set_avi_playtimer_id(0);
if (ui_in_effect()) {
if (ui_in_effect() || dial_sel_state()) {
if (get_aviplay_handle() != NULL) {
avi_pause();
}
@@ -859,6 +864,7 @@ static int WATCH_onchange(void *ctr, enum element_change_event e, void *arg)
u8 slow_sec = 0;
#if TCFG_VIDEO_DIAL_ENABLE
u16 avi_playtimer ;
static u8 watch_mode_type = 0;
#endif
/* printf("%s %d", __func__, e); */
switch (e) {
@@ -887,10 +893,24 @@ static int WATCH_onchange(void *ctr, enum element_change_event e, void *arg)
ui_page_move_en_callback(is_ui_page_move_enable);
watch_load_sidebar(elm);
watch_dial_bgp_init(&dial_param);
#if TCFG_VIDEO_DIAL_ENABLE
syscfg_read(CFG_DIAL_TYPE_SEL, (u8 *)&watch_mode_type, 1);
#endif
ui_auto_shut_down_enable();
break;
#if TCFG_VIDEO_DIAL_ENABLE
case ON_CHANGE_SHOW_POST:
if (watch_mode_type == 1) {
if (ui_in_effect() || ui_page_get_busy() || dial_sel_state()) {
char *bg_path = watch_avi_get_related_path(watch_get_style());
if (bg_path) {
extern int jpeg_image_file_psram(struct draw_context * dc, int left, int top, int width, int height, char *path, int path_len, int scale_en, float scale_f);
jpeg_image_file_psram(dc, 0, 0, 320, 384, bg_path, strlen(bg_path), 0, 1.0f);
}
}
}
// 保护措施,防止avi资源释放后访问空指针
if (get_avi_pause_status()) {
// printf("\n\n avi_player is already free!!!!!!!\n");
@@ -709,6 +709,7 @@ void hexagon_effect_init(struct element *curr_elm, bool list_flag)
if (__this->init) {
return;
}
if (polytope == POLYTOPE_SIX) {
__this->polytope_type = POLYTOPE_SIX;
} else if (polytope == POLYTOPE_EIGHT) {
@@ -721,6 +722,7 @@ void hexagon_effect_init(struct element *curr_elm, bool list_flag)
return;
}
__this->init = 1;
struct ui_platform_api *platform_api = ui_get_platform_api();
ASSERT(platform_api);
struct draw_context dc_tmp = {0};
@@ -892,7 +894,7 @@ void hexagon_effect_init(struct element *curr_elm, bool list_flag)
}
}
__this->init = 1;
/* __this->init = 1; */
}
/* ------------------------------------------------------------------------------------*/
@@ -742,6 +742,7 @@ void reflection_effect_init(struct element *curr_elm, bool list_flag)
return;
}
__this->init = 1;
struct ui_platform_api *platform_api = ui_get_platform_api();
ASSERT(platform_api);
struct draw_context dc_tmp = {0};
@@ -879,7 +880,7 @@ void reflection_effect_init(struct element *curr_elm, bool list_flag)
}
}
__this->init = 1;
/* __this->init = 1; */
}
/* ------------------------------------------------------------------------------------*/
@@ -46,6 +46,7 @@
// ui参数
struct ifly_ui_t {
u8 vad_button; // 判断vad是否按下,防止多次开启
u8 net_fail;
u16 time_id; // 定时器
u16 task_create_timer;
@@ -86,6 +87,17 @@ static bool ifly_check_net_connect(void)
return false;
}
static void ui_ifly_vad_button_touch(u8 flag)
{
ifly_ui->vad_button = flag;
}
static u8 ui_ifly_vad_button_get_touch()
{
return ifly_ui->vad_button;
}
static int ui_ifly_ai_event_cb(ifly_ai_event_enum evt, void *param)
{
switch (evt) {
@@ -121,6 +133,7 @@ static int ui_ifly_vad_event_cb(ifly_vad_event_enum evt, void *param)
sys_timeout_del(ifly_ui->vad_recv_timer);
ifly_ui->vad_recv_timer = 0;
}
ui_ifly_vad_button_touch(0);
break;
case IFLY_VAD_EVT_NETWORK_RECV_ERROR:
UI_MSG_POST("vad_network_recv_error");
@@ -414,12 +427,14 @@ static void vad_recv_timer_handler(void *priv)
sys_timeout_del(ifly_ui->vad_recv_timer);
ifly_ui->vad_recv_timer = 0;
}
ui_ifly_vad_button_touch(0);
}
static int ifly_vad_button_ontouch(void *ctr, struct element_touch_event *e)
{
switch (e->event) {
case ELM_EVENT_TOUCH_DOWN:
if (!ui_ifly_vad_button_get_touch()) {
if (!ifly_vad_is_work()) {
// 开始
if (ifly_check_net_connect() == false) {
@@ -437,11 +452,13 @@ static int ifly_vad_button_ontouch(void *ctr, struct element_touch_event *e)
ifly_vad_start(&p_ifly_net->vad_param);
} else {
// 停止
ifly_vad_stop(0, 2000);
log_info("stop recording\n");
if (!ifly_ui->vad_recv_timer) {
ifly_ui->vad_recv_timer = sys_timeout_add(NULL, vad_recv_timer_handler, 3000);
}
ui_ifly_vad_button_touch(1);
ifly_vad_stop(0, 2000);
log_info("stop recording\n");
}
}
break;
default:
@@ -646,6 +663,7 @@ static int vad_network_fail()
ifly_ui->cur_layout = IFLY_LAYOUT_CONNECTTING;
ifly_ui->show_layout = IFLY_LAYOUT_CONNECT_FAIL;
ifly_no_content(IFLY_VAD_NO_CONN_CNT_MAX);
ui_ifly_vad_button_touch(1);
return 0;
}
@@ -655,6 +673,7 @@ static int vad_network_recv_error()
ifly_ui->cur_layout = IFLY_LAYOUT_VAD;
ifly_ui->show_layout = IFLY_LAYOUT_CONNECT_FAIL;
ifly_no_content(IFLY_VAD_NO_CONN_CNT_MAX);
ui_ifly_vad_button_touch(1);
return 0;
}
+178 -67
View File
@@ -84,24 +84,10 @@
#include "avi_video.h"
#include "avi_audio_player.h"
#if TCFG_VIDEO_DIAL_ENABLE
#define AVI_TASK_NAME "avi_task"
#define NEW_PARSE_RIFF_FILE 1 // 该宏打开使用新的文件解析流程,与旧流程主要区别在于兼容packres工具打包后的avi资源解析
#define DEFAULT_DWSUGGESTEDBUFFER_SIZE 20*1024
#define PCM_CBUF_SIZE (4*1024) /* 根据负载可调 320B*3帧约等于1KB */
enum avi_status {
AVI_PLAY_STATUS = 1,
AVI_STOP_STATUS,
};
enum {
MIC2DAC_STATUS_STOP = 0,
MIC2DAC_STATUS_START,
MIC2DAC_STATUS_PAUSE, // 暂时未添加这个状态
};
enum {
AVI_PLAY_ONCE = 0,
AVI_PLAY_LOOP,
AVI_PLAY_SEQUENCE,
};
#define PCM_CBUF_SIZE (20*1024) /* 根据负载可调 320B*3帧约等于1KB */
struct avi_fs_info {
FILE *fp;
u32 offset;
@@ -111,10 +97,9 @@ struct avi_fs_info {
};
cbuffer_t avi_pcm_cbuf;
OS_MUTEX avi_pcm_mutex;
u8 usr_test_flag = 0;
static u8 avi_play_mode = 0;
static u8 avi_play_mode = AVI_PLAY_LOOP;
static MV_DRAW *avi_player = NULL;
static PLAY_VIDEO_PATH_MANAGE *video_path_mange = NULL;
#define __this (avi_player)
/* static void *gpu_task_head; */
static void *avi_taskp;
@@ -124,6 +109,7 @@ static const char *avi_files[] = {
// 可以继续添加更多文件
};
static u16 task_switch_flag;
/* static u8 __this->param.is_audio_mute = 1; */
#define AVI_FILE_COUNT (sizeof(avi_files) / sizeof(avi_files[0]))
@@ -164,11 +150,13 @@ extern u32 ps_ram_size[];
extern int avi_get_width(void *avip);
extern int avi_get_height(void *avip);
extern int avi_fluh(void *priv);
extern void malloc_list_update_rets(void *buf, int rets);
void avi_stop(void *avip);
void avi_pause(void *avip);
void animig_close(void *ap);
/* void *animig_open(char *name, AVI_PARAM param, int arg); */
@@ -178,6 +166,10 @@ void animig_close(void *ap);
static void *avi_zalloc(size_t size)
{
u32 rets;
__asm__ volatile("%0 = rets":"=r"(rets));
void *p = NULL;
#if TCFG_PSRAM_DEV_ENABLE
p = malloc_psram(size);
@@ -185,16 +177,23 @@ static void *avi_zalloc(size_t size)
#else
p = zalloc(size);
#endif
malloc_list_update_rets(p, rets);
return p;
}
static void *avi_malloc(size_t size)
{
u32 rets;
__asm__ volatile("%0 = rets":"=r"(rets));
void *p = NULL;
#if TCFG_PSRAM_DEV_ENABLE
p = malloc_psram(size);
#else
p = malloc(size);
#endif
malloc_list_update_rets(p, rets);
return p;
}
static void avi_free(void *pv)
@@ -216,7 +215,6 @@ static void pcm_cbuf_init(void)
}
ASSERT(__this->avi_pcm_buf, "pcm cbuf avi_malloc fail\n");
cbuf_init(&avi_pcm_cbuf, __this->avi_pcm_buf, PCM_CBUF_SIZE);
os_mutex_create(&avi_pcm_mutex);
__this->avi_audio_start = 1;
log_info("\n[pcm_cbuf_init]mem_status:\n");
mem_stats();
@@ -229,7 +227,6 @@ static void pcm_cbuf_deinit(void)
cbuf_clear(&avi_pcm_cbuf);
avi_free(__this->avi_pcm_buf);
__this->avi_pcm_buf = NULL;
os_mutex_del(&avi_pcm_mutex, 0);
}
log_info("\n[pcm_cbuf_deinit]mem_status:\n");
mem_stats();
@@ -314,20 +311,72 @@ void avi_play_shutdown(void)
log_info("\n\n[avi_play_shutdown]mem_status:\n");
mem_stats();
}
void video_manage_init()
{
video_path_mange = avi_zalloc(sizeof(PLAY_VIDEO_PATH_MANAGE));
}
void set_avi_play_mode(u8 mode)
{
avi_play_mode = mode;
avi_play_shutdown();
}
// 播放下一个文件
void *animig_open(char *name, int window_id, int arg);
void avi_play_next(void)
{
AVI_PARAM param;
if (__this != NULL) {
memcpy(&param, &(__this->param), sizeof(AVI_PARAM));//拷贝当前配置
}
u8 is_dial = __this->param.is_dial;
u8 *video_path = NULL;
if (is_dial == 0) {
video_path = (u8 *)param.fname;
} else {
video_path = (u8 *)watch_avi_get_related_path(watch_get_style());
}
if (video_path == NULL) {
log_error("%s path is NULL");
return ;
}
if (!__this->avi_is_switching) {
avi_switch_timelock();
wdt_clear();
avi_play_shutdown();
avi_player = animig_open((char *)watch_avi_get_related_path(watch_get_style()), 0, 3); // 缓存3帧可以达到流畅播放30FPS
avi_player = animig_open((char *)video_path, param, 3); // 缓存3帧可以达到流畅播放30FPS
/* avi_player = (MV_DRAW *) animig_open((char *)set_avi_play_file(), 0, 3); // 缓存3帧可以达到流畅播放30FPS */
__this->avi_playtimer = 0;
// UI_HIDE_CURR_WINDOW();
// UI_SHOW_WINDOW(AVI_WINDOW);
// UI_SHOW_WINDOW(STYLE_DIAL_ID(WATCH));
}
}
void avi_play_loop(void)
{
AVI_PARAM param;
if (__this != NULL) {
memcpy(&param, &(__this->param), sizeof(AVI_PARAM));//拷贝当前配置
}
u8 is_dial = __this->param.is_dial;
u8 *video_path = NULL;
if (is_dial == 0) {
video_path = (u8 *)param.fname;
} else {
video_path = (u8 *)watch_avi_get_related_path(watch_get_style());
}
if (video_path == NULL) {
log_error("%s path is NULL");
return ;
}
if (!__this->avi_is_switching) {
avi_switch_timelock();
wdt_clear();
avi_play_shutdown();
avi_player = animig_open((char *)video_path, param, 3); // 缓存3帧可以达到流畅播放30FPS
/* avi_player = (MV_DRAW *) animig_open((char *)set_avi_play_file(), 0, 3); // 缓存3帧可以达到流畅播放30FPS */
__this->avi_playtimer = 0;
// UI_HIDE_CURR_WINDOW();
@@ -338,17 +387,35 @@ void avi_play_next(void)
// 播放上一个文件
void avi_play_prev(void)
{
AVI_PARAM param;
if (__this != NULL) {
memcpy(&param, &(__this->param), sizeof(AVI_PARAM));//拷贝当前配置
}
u8 is_dial = __this->param.is_dial;
u8 *video_path = NULL;
if (is_dial == 0) {
video_path = (u8 *)param.fname;
} else {
video_path = (u8 *)watch_avi_get_related_path(watch_get_style());
}
if (video_path == NULL) {
log_error("%s path is NULL");
return ;
}
if (!__this->avi_is_switching) {
avi_switch_timelock();
wdt_clear();
avi_play_shutdown();
__this->avi_index--;
if (__this->avi_index < 0) {
__this->avi_index = AVI_FILE_COUNT - 1;
}
avi_player = animig_open((char *)video_path, param, 3); // 缓存3帧可以达到流畅播放30FPS
/* avi_player = (MV_DRAW *) animig_open((char *)set_avi_play_file(), 0, 3); // 缓存3帧可以达到流畅播放30FPS */
__this->avi_playtimer = 0;
// UI_HIDE_CURR_WINDOW();
// UI_SHOW_WINDOW(AVI_WINDOW);
// UI_SHOW_WINDOW(STYLE_DIAL_ID(WATCH));
}
}
@@ -364,7 +431,7 @@ static size_t avi_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
#define rewind(fp) fseek(fp, 0, SEEK_SET)
void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int curr_pos)
char parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int curr_pos)
{
char *head = "";
@@ -391,13 +458,13 @@ void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int c
/* 读取RIFF头 */
if (avi_fread(chunk_id, 1, 4, file) != 4) {
log_error("Failed to read chunk ID");
return;
return -AVI_READ_CHUNK_ID_FAIL;
}
chunk_id[4] = '\0';
if (avi_fread(&chunk_size, 4, 1, file) != 1) {
log_error("Failed to read chunk size");
return;
return -AVI_READ_CHUNK_SIZE_FAIL;
}
log_info("\n\n\n\n\nRIFF chunk_size: %d\n\n\n\n\n", chunk_size);
/* 校验块大小合法性 */
@@ -406,7 +473,7 @@ void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int c
if (current_pos + chunk_size > file_size) {
log_info("校验块大小合法性 %d %d %d", (int)current_pos, chunk_size, (int)file_size);
log_error("RIFF chunk size exceeds file size");
return;
return -AVI_FILE_LEN_ERR;
}
/* 处理子块 */
@@ -422,13 +489,13 @@ void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int c
/* 读取子块头 */
if (avi_fread(sub_chunk_id, 1, 4, file) != 4) {
log_error("Failed to read sub chunk ID");
return;
return -AVI_READ_SUB_CHUNK_ID_FAIL;
}
sub_chunk_id[4] = '\0';
if (avi_fread(&sub_chunk_size, 4, 1, file) != 1) {
log_error("Failed to read sub chunk size");
return;
return -AVI_READ_SUB_CHUNK_ID_FAIL;
}
/* 校验子块大小 */
@@ -436,7 +503,7 @@ void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int c
if (current_pos + sub_chunk_size > file_size) {
log_info("校验子块大小 %d %d %d", (int)current_pos, sub_chunk_size, (int)file_size);
log_error("Sub chunk exceeds file size");
return;
return -AVI_SUB_CHUNK_LEN_ERR;
}
off_t sub_start = ftell(file) - 8 - __this->file_offset; // 计算子块起始位置
@@ -447,7 +514,7 @@ void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int c
char list_type[5] = {0};
if (avi_fread(list_type, 1, 4, file) != 4) {
log_error("Failed to read LIST type");
return;
return -AVI_LIST_TYPE_ERR;
}
list_type[4] = '\0';
@@ -487,6 +554,7 @@ void parse_riff_file(FILE *file, ChunkCallback callback, void *user_param, int c
fseek(file, 1, SEEK_CUR);
}
}
return 0;
}
/* LIST块解析实现 */
static void parse_list_chunk(FILE *file, long list_end, ChunkCallback callback,
@@ -804,15 +872,16 @@ void *avi_open(const char *path, int en_buf, int redrawid)
log_info("%s %d %s", __func__, __LINE__, path);
FILE *fp = fopen(path, "r");
AVIPlayer *player = avi_zalloc(sizeof(AVIPlayer));
wdt_clear();
log_info("%s %d fp %p", __func__, __LINE__, fp);
mem_stats();
if (!fp) {
return NULL;
log_error("%s open file fail ");
goto __err;
}
log_info("%s %d", __func__, __LINE__);
mem_stats();
AVIPlayer *player = avi_zalloc(sizeof(AVIPlayer));
player->file = fp;
player->redrawid = redrawid;
log_info("%s %d", __func__, __LINE__);
@@ -820,14 +889,19 @@ void *avi_open(const char *path, int en_buf, int redrawid)
// 解析文件结构
log_info("\n\n\nBefore parse_riff_file: file position: %u\n", ftell(fp));
parse_riff_file(fp, parse_callback, player, 0);
char parse_ret = parse_riff_file(fp, parse_callback, player, 0);
if (parse_ret != 0) {
log_error("%s check file fail =%d", __func__, parse_ret);
goto __err;
}
log_info("%s %d", __func__, __LINE__);
mem_stats();
rewind(fp);
if (player->avih_header.dwTotalFrames == 0) {
avi_free(player);
return NULL;
log_error("%s frames info no get ");
goto __err;
}
void *usr_mmu = strstr(path, "virfat_flash");
@@ -853,7 +927,7 @@ void *avi_open(const char *path, int en_buf, int redrawid)
player->cache.cnt = en_buf;
player->cache.block_len = len;
player->cache.data = malloc_psram(player->cache.cnt * player->cache.block_len);
player->cache.data = avi_zalloc(player->cache.cnt * player->cache.block_len);
ASSERT(player->cache.data);
player->cache.m = avi_zalloc(player->cache.cnt * sizeof(mjpegdata));
@@ -891,6 +965,12 @@ void *avi_open(const char *path, int en_buf, int redrawid)
os_mutex_create(&p->mutex);
return player;
__err:
printf("\n [ERROR] %s -[yuyu] %d\n", __FUNCTION__, __LINE__);
void avi_close(void *avip);
avi_close(player);
return NULL;
}
void avi_close(void *avip)
@@ -997,10 +1077,9 @@ void avi_pause()
/* AVIPlayer *p = (AVIPlayer *)avip; */
AVIPlayer *p = (AVIPlayer *)__this->st;
if (avi_player == NULL || avi_player->pause == 1) {
if (__this == NULL || __this->pause == 1 || p == NULL) {
return;
}
printf("\n [ERROR] %s -[yuyu] %d\n", __FUNCTION__, __LINE__);
p->ui_work = 2;
avi_player->pause = 1;
@@ -1020,7 +1099,9 @@ void avi_pcm_open(void *avip)
{
AVIPlayer *p = (AVIPlayer *)avip;
// 初始化循环缓冲区和互斥锁
if (p->audio_format.wFormatTag == 0) {
return ;
}
pcm_cbuf_init();
// 创建AI voice播放参数
@@ -1053,6 +1134,9 @@ void avi_pcm_open(void *avip)
void avi_pcm_close(void *avip)
{
AVIPlayer *p = (AVIPlayer *)avip;
if (p->audio_format.wFormatTag == 0) {
return ;
}
log_info("%s %d ", __func__, __LINE__);
pcm_cbuf_deinit();
@@ -1118,7 +1202,7 @@ int avi_exec(void *avip, DisplayMJpegFunc jpgcb, PlayPCMFunc pcmcb)
AVIPlayer *p = (AVIPlayer *)avip;
int argv[2] = {0};
int ret;
// log_info("%s %d is_playing %d", __func__, __LINE__, p->is_playing);
/* log_info("%s %d is_playing %d,", __func__, __LINE__, p->is_playing); */
if (!p) {
return -1;
@@ -1135,8 +1219,12 @@ int avi_exec(void *avip, DisplayMJpegFunc jpgcb, PlayPCMFunc pcmcb)
switch (avi_play_mode) {
case AVI_PLAY_LOOP:
// 默认模式,单视频循环
p->current_pos = 0;
avi_seek(avip, 0.0);
/* p->current_pos = 0; */
/* avi_seek(avip, 0.0); */
argv[0] = (int)avi_play_loop;
argv[1] = 0;
ret = os_taskq_post_type("ui", Q_CALLBACK, 2, argv);
log_info("\n\n[AVI_PLAY_LOOP]%s %d is_playing %d\n\n", __func__, __LINE__, p->is_playing);
return -1;
break;
@@ -1677,11 +1765,10 @@ static int _write_jlaudio(void *player, u8 *ptr, int len)
AVIPlayer *pp = (AVIPlayer *)player;
// log_info("[_write_aivoice] len:%d\n", len);
int cnt = 0;
if (__this->param.is_audio_mute != 1) {
while (len) {
/* os_mutex_pend(&avi_pcm_mutex, 0); */
u32 w = cbuf_write(&avi_pcm_cbuf, ptr, len); // 直接按len写,返回实际写入
// log_info("[cbuf_write] w:%d\n", w);
/* os_mutex_post(&avi_pcm_mutex); */
/* log_info("[cbuf_write] w:%d len=%d\n", w, len); */
if (w == 0) {
os_time_dly(1);
continue;
@@ -1689,6 +1776,7 @@ static int _write_jlaudio(void *player, u8 *ptr, int len)
ptr += w;
len -= w;
}
}
pp->jump_mjpeg = jiffies_usec();
return len;
}
@@ -1890,6 +1978,7 @@ static void md_flush(MV_DRAW *md)
// log_info("11 %d", jiffies_msec());
AVIPlayer *p = (AVIPlayer *)md->st;
/* printf("[msg]%s-%d>>>>>>>>>>>md->pause=%d,p->avih_header.dwMicroSecPerFrame=%d p->audio_format.wFormatTag=%d", __FUNCTION__, __LINE__, md->pause, p->avih_header.dwMicroSecPerFrame, p->audio_format.wFormatTag); */
if (md->pause == 1) {
md->flushTimer = sys_timeout_add(md, (void(*)(void *))md_flush, p->avih_header.dwMicroSecPerFrame / 2000);
@@ -1898,7 +1987,7 @@ static void md_flush(MV_DRAW *md)
avi_fluh(md->st);
if (p->audio_format.wFormatTag == 0x0001) {
if (p->audio_format.wFormatTag == 0x0001 && __this->param.is_audio_mute != 1) {
md->flushTimer = sys_timeout_add(md, (void(*)(void *))md_flush, p->avih_header.dwMicroSecPerFrame / 2000);
} else {
md->flushTimer = sys_timeout_add(md, (void(*)(void *))md_flush, p->avih_header.dwMicroSecPerFrame / 1000);
@@ -1926,14 +2015,16 @@ void play_task(MV_DRAW *md)
// play
if (msg[1] == AVI_PLAY_STATUS) {
log_info("avi play");
avi_pcm_open(md->st);
md->flushTimer = sys_timeout_add(md, (void(*)(void *))md_flush, 1);
}
// stop
if (msg[1] == AVI_STOP_STATUS) {
log_info("avi stop");
if (__this->param.is_audio_mute != 1) {
avi_pcm_close(md->st);
}
if (md->flushTimer) {
sys_timeout_del(md->flushTimer);
md->flushTimer = 0;
@@ -1973,7 +2064,7 @@ static void app_video_mode_switch(void *priv)
}
#endif
void *animig_open(char *name, int window_id, int arg)
void *animig_open(char *name, AVI_PARAM param, int arg)
{
u8 type = 0;
@@ -1987,7 +2078,7 @@ void *animig_open(char *name, int window_id, int arg)
}
#endif
void *f = fopen(name, "r");
FILE *f = fopen(name, "r");
if (f == NULL) {
log_info("open file fail %s", name);
return NULL;
@@ -2014,42 +2105,62 @@ void *animig_open(char *name, int window_id, int arg)
MV_DRAW *md = avi_zalloc(sizeof(MV_DRAW));
__this = md;
ASSERT(__this);
memcpy(&(__this->param), &param, sizeof(AVI_PARAM));
os_sem_create(&md->mv_sem, 0);
md->type = type;
md->repeat = -1;
if (md->type == 2) {
md->st = avi_open(name, arg, 0);
AVIPlayer *p = (AVIPlayer *)(md->st);
if (md->st == NULL) {
goto __err;
}
if (p->width > LCD_WIDTH || p->height > LCD_HEIGHT) {
log_error("vidoe width %d or height%d over lcd width %d or height %d", p->width, p->height, LCD_WIDTH, LCD_HEIGHT);
goto __err;
}
if (__this->param.is_audio_mute != 1) {
avi_pcm_open(md->st);
}
wdt_clear();
ASSERT(md->st);
avi_fluh(md->st);
}
/* strcpy(__this->param.fname,name,) */
/* char *taskname = strrchr(name, '/'); */
/* taskname = taskname ? taskname + 1 : name; */
/* taskname = "avi_task"; */
u8 fname_len = (sizeof(__this->param.fname) / sizeof(__this->param.fname[0]));
strncpy(__this->param.fname, name, fname_len);
printf("[msg]%s-%d>>>>>>>>>>>__this->param.fname=%s", __FUNCTION__, __LINE__, __this->param.fname);
__this->param.fname[fname_len - 1] = '\0';
log_info("create %s", AVI_TASK_NAME);
task_create((void(*)(void *))play_task, md, AVI_TASK_NAME);
char *taskname = strrchr(name, '/');
taskname = taskname ? taskname + 1 : name;
taskname = "avi_task";
strcpy(md->fname, taskname);
log_info("create %s", taskname);
task_create((void(*)(void *))play_task, md, "avi_task");
os_taskq_post(md->fname, 1, AVI_PLAY_STATUS);
os_taskq_post(AVI_TASK_NAME, 1, AVI_PLAY_STATUS);
return md;
__err:
void avi_close(void *avip);
avi_close(md->st);
__this = NULL;
if (md) {
avi_free(md);
}
return NULL;
}
void animig_close(void *ap)
{
MV_DRAW *md = ap;
char *taskname = strrchr(md->fname, '/');
taskname = taskname ? taskname + 1 : md->fname;
// while (md->act != -1) {
// md->act = 0;
// os_time_dly(1);
// }\\
os_taskq_post(md->fname, 1, AVI_STOP_STATUS);
os_taskq_post(AVI_TASK_NAME, 1, AVI_STOP_STATUS);
os_sem_pend(&md->mv_sem, 0);
log_info("kill %s", taskname);
log_info("kill %s", AVI_TASK_NAME);
jlgpu_scheduler_wait_sync();
task_kill("avi_task");
+43 -3
View File
@@ -92,6 +92,21 @@ typedef void (*ChunkCallback)(FILE *file,
#pragma pack(push, 1)
enum avi_status {
AVI_PLAY_STATUS = 1,
AVI_STOP_STATUS,
};
enum {
MIC2DAC_STATUS_STOP = 0,
MIC2DAC_STATUS_START,
MIC2DAC_STATUS_PAUSE, // 暂时未添加这个状态
};
enum {
AVI_PLAY_ONCE = 0,
AVI_PLAY_LOOP,
AVI_PLAY_SEQUENCE,
};
typedef struct {
uint32_t dwMicroSecPerFrame; // 每帧时长(微秒)
@@ -175,6 +190,17 @@ typedef enum {
STREAM_AUDIO
} StreamType;
typedef enum {
AVI_READ_CHUNK_ID_FAIL = 1,
AVI_READ_CHUNK_SIZE_FAIL,
AVI_READ_SUB_CHUNK_ID_FAIL,
AVI_READ_SUB_CHUNK_SIZE_FAIL,
AVI_LIST_TYPE_ERR,
AVI_FILE_LEN_ERR,
AVI_SUB_CHUNK_LEN_ERR
} AVI_ERR_CODE;
typedef struct {
// 文件信息
FILE *file;
@@ -205,8 +231,8 @@ typedef struct {
int bits_per_sample;
u8 auds_vol;
u8 auds_drop;
int auds_idx;
u8 auds_exit;
int auds_idx;
u16 auds_inr;
int auds_rate;
int auds_total;
@@ -243,8 +269,14 @@ void *avi_open(const char *path, int en_buf, int redrawid);
void avi_close(void *avip);
int avi_fluh(void *priv);
typedef struct {
void *fp;
u8 is_dial;
u8 is_audio_mute;
u8 mode;
char fname[64];
} AVI_PARAM;
typedef struct {
void *fp;
OS_SEM mv_sem;
void *st; // 解码器
int drawid;
@@ -257,6 +289,7 @@ typedef struct {
u8 avi_is_switching;
u8 avi_index;
u16 avi_playtimer;
AVI_PARAM param;
int start;
int time;
int frameCount;
@@ -265,6 +298,12 @@ typedef struct {
u8 *avi_pcm_buf;
long file_offset;
} MV_DRAW;
typedef struct {
u8 **file_path;
u8 *cur_index;
} PLAY_VIDEO_PATH_MANAGE;
@@ -294,7 +333,8 @@ int avi_get_redrawid(void *avip);
float avi_get_total_sec(void *avip);
void *avi_get_view_file_info(void *priv);
void *animig_open(char *name, int window_id, int arg);
// void *animig_open(char *name, int window_id, int arg);
void *animig_open(char *name, AVI_PARAM param, int arg);
void avi_set_avi_playtimer_id(u16 timer_id);
u16 avi_get_avi_playtimer_id();
+3
View File
@@ -275,6 +275,7 @@ int mic_data_write(void *mic, void *data, int len)
struct voice_mic_data *fb = (struct voice_mic_data *)mic;
int wlen = 0;
wlen = cbuf_write(&fb->cbuf, data, len);
//如果有较多丢包,要开下读的putchar打印,评估是否需要加大cbuf
if (wlen < len) {
putchar('D');
}
@@ -285,9 +286,11 @@ int mic_data_read(void *mic, void *data, int len)
struct voice_mic_data *fb = (struct voice_mic_data *)mic;
/* printf("%s. %d, %d", __func__, len, cbuf_get_data_len(&fb->cbuf)); */
if (cbuf_get_data_len(&fb->cbuf) < len) {
/* putchar('B'); */
return 0;
} else {
int wlen = cbuf_read(&fb->cbuf, data, len);
/* putchar('G'); */
return wlen;
}
}
+195 -5
View File
@@ -4,6 +4,7 @@
#include "camera_manager.h"
#include "avilib.h"
#include "pcm_data.h"
#include "mic_data.h"
#include "clock_manager/clock_manager.h"
#define LOG_TAG_CONST VIDEO_REC
@@ -15,6 +16,16 @@
#define LOG_CLI_ENABLE
#include "debug.h"
#if TCFG_CAMERA_MANAGER_ENABLE
/*
使pcm线程管理mic数据,
ram(11*4k)mic数据仅需要(3*4k+512)
*/
#define MIC_DATA_FORM_PCM_TASK_ENABLE 0
#define MIC_FREMA_SIZE (4*1024)
#define MIC_BUFFER_SIZE (MIC_FREMA_SIZE*2+512)
#define MIC_SIMPLE_RATE (8000)
enum {
Q_AVI_TASK_KILL = (Q_USER + 100),
@@ -22,8 +33,23 @@ enum {
Q_AVI_TASK_REC_STOP,
};
struct fill_frame {
u32 start_msecs;//开始录像时间
u32 msecs;//上一次补帧时间
u32 secs;//录像时间
u32 fnum;//需要补帧的数
u32 cnt_fnum;//总帧数
u16 fps;//目标帧率
u16 one_sec_fps;//1秒实际帧率
u8 fill_frame_en;
u8 droping_frame_en;
};
struct video_rec_handle {
void *pcm_hdl;
void *mic;
u8 *mic_frame;
char avi_task_name[32];
u8 write_error; //写文件异常
u8 busy;
@@ -32,10 +58,20 @@ struct video_rec_handle {
int sample_rate;
void (*ui_refresh_cb)(int status);
int bytes_per_sample;
struct fill_frame fill;
};
static struct video_rec_handle *video_rec;
#define __this (video_rec)
#if TCFG_PSRAM_DEV_ENABLE
#define malloc(size) malloc_psram(size)
#define free(ptr) free_psram(ptr)
#else
#define malloc(size) malloc(size)
#define free(ptr) free(ptr)
#endif
extern uint32_t timer_get_ms(void);
@@ -112,6 +148,101 @@ int jlcamera_video_rec_stop()
return os_taskq_post_type(__this->avi_task_name, Q_AVI_TASK_REC_STOP, 0, NULL);
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static void jljpeg_frame_fill_init()
{
if (!__this) {
log_error("%s not init\n", __func__);
return;
}
memset(&__this->fill, 0, sizeof(struct fill_frame));
__this->fill.fps = __this->video_rate;
__this->fill.start_msecs = jiffies_msec();;
__this->fill.msecs = jiffies_msec();
__this->fill.droping_frame_en = 1;
__this->fill.fill_frame_en = 1;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief ()
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static void jljpeg_frame_fill_judge(avi_t *out_fd, u32 frame_cnt)
{
if (!__this) {
log_error("%s not init\n", __func__);
return;
}
u32 cur_fcnt;
u32 need_fcnt;
__this->fill.cnt_fnum += frame_cnt;
__this->fill.one_sec_fps += frame_cnt;
if (jiffies_msec2offset(__this->fill.msecs, jiffies_msec()) >= 1000) {
__this->fill.secs = (jiffies_msec2offset(__this->fill.start_msecs, jiffies_msec())) / 1000;
if (!__this->fill.secs) {
__this->fill.secs = 1;
}
need_fcnt = __this->fill.secs * __this->fill.fps;
cur_fcnt = __this->fill.cnt_fnum + __this->fill.fnum;
if (cur_fcnt < need_fcnt) {
__this->fill.fnum += need_fcnt - cur_fcnt;
}
__this->fill.msecs = jiffies_msec();
/* printf("avi dup video fps :%d act fps:%d ,ext fps: %d %d\n", __this->fill.cnt_fnum / __this->fill.secs, __this->fill.one_sec_fps, __this->fill.fps,__this->fill.fnum); */
__this->fill.one_sec_fps = 0;
}
if (__this->fill.fnum && __this->fill.fill_frame_en) {
int ret = AVI_dup_frame(out_fd);
if (!ret) {
__this->fill.cnt_fnum++;
__this->fill.fnum--;
}
}
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief ()
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int jljpeg_frame_dropping_judge()
{
if (!__this || !__this->fill.droping_frame_en) {
return 0;
}
u32 msecs = jiffies_msec2offset(__this->fill.msecs, jiffies_msec());
/* printf("%d %d %d\n",(__this->fill.one_sec_fps+1) , (msecs*__this->fill.fps/1000),msecs); */
if ((__this->fill.one_sec_fps) > (msecs * __this->fill.fps / 1000) + 1) {
/* printf("fps > %d ,need droping\n",__this->fill.fps); */
if (__this->fill.fnum) {
__this->fill.fnum--;
return 0;
}
return 1;
}
return 0;
}
static void video_show_task(void *priv)
{
log_debug("%s enter>>>>>>>>>>>>>>>>>>>>\n ", __func__);
@@ -148,10 +279,21 @@ static void video_show_task(void *priv)
out_fd = NULL;
}
}
#if MIC_DATA_FORM_PCM_TASK_ENABLE
if (__this->pcm_hdl) {
pcm_data_exit(__this->pcm_hdl);
__this->pcm_hdl = NULL;
}
#else
if (__this->mic) {
mic_data_close(__this->mic);
__this->mic = NULL;
}
if (__this->mic_frame) {
free(__this->mic_frame);
__this->mic_frame = NULL;
}
#endif
log_debug("%s exit >>>>>>>>>>>>>>>>>>>>\n ", __func__);
//下面禁止加打印{
os_sem_post((OS_SEM *)msg[1]);
@@ -163,7 +305,7 @@ static void video_show_task(void *priv)
cyc_time = msg[2];
__this->write_error = 0;
log_debug("avi task rec start <%s> cyc_time:%d !\n", filename, cyc_time);
#if MIC_DATA_FORM_PCM_TASK_ENABLE
__this->pcm_hdl = pcm_data_init(__this->sample_rate, __this->aframe_size, __this->aframe_size * 10);
if (!__this->pcm_hdl) {
//TODO
@@ -172,6 +314,23 @@ static void video_show_task(void *priv)
__this->write_error = -1;
continue;
}
#else
__this->mic = mic_data_open(VOICE_MCU_MIC, MIC_BUFFER_SIZE, MIC_SIMPLE_RATE);
if (!__this->mic) {
//TODO
log_error("avi task rec start pcm err!!!\n");
/* break; */
__this->write_error = -1;
continue;
}
__this->mic_frame = malloc(MIC_FREMA_SIZE);
if (!__this->mic_frame) {
log_error("avi task rec start pcm err!!!\n");
/* break; */
__this->write_error = -1;
continue;
}
#endif
out_fd = AVI_open_output_file(filename);
if (out_fd == NULL) {
log_error("open file erro\n");
@@ -182,6 +341,7 @@ static void video_show_task(void *priv)
AVI_set_video_suggestbuffersize(out_fd, 20 * 1024); //建议缓存区20k,解码用
AVI_set_video(out_fd, frame_width, frame_height, __this->video_rate, "MJPG");
AVI_set_audio(out_fd, 1, __this->sample_rate, 16, WAVE_FORMAT_PCM, 0);//默认单声道s16格式
jljpeg_frame_fill_init();
frame_cnt = 0;
/* break; */
} else if (msg[0] == Q_AVI_TASK_REC_STOP) {
@@ -197,11 +357,21 @@ static void video_show_task(void *priv)
}
out_fd = NULL;
}
#if MIC_DATA_FORM_PCM_TASK_ENABLE
if (__this->pcm_hdl) {
pcm_data_exit(__this->pcm_hdl);
__this->pcm_hdl = NULL;
}
#else
if (__this->mic) {
mic_data_close(__this->mic);
__this->mic = NULL;
}
if (__this->mic_frame) {
free(__this->mic_frame);
__this->mic_frame = NULL;
}
#endif
__this->write_error = 0;
/* break; */
}
@@ -212,11 +382,20 @@ static void video_show_task(void *priv)
log_char('C');
//录像输出
if (out_fd) {
#if MIC_DATA_FORM_PCM_TASK_ENABLE
if (pcm_data_read(__this->pcm_hdl, &pcm_data, &pcm_data_len) == 0) {
read_data = 1;
__this->write_error = AVI_write_audio(out_fd, (char *)pcm_data, pcm_data_len);
pcm_data_read_done(__this->pcm_hdl, pcm_data);
}
#else
if (__this->mic && __this->mic_frame) {
if (mic_data_read(__this->mic, __this->mic_frame, MIC_FREMA_SIZE)) {
read_data = 1;
__this->write_error = AVI_write_audio(out_fd, (char *)__this->mic_frame, MIC_FREMA_SIZE);
}
}
#endif
}
if (camera_manager_data_read(&jpeg_data, &jpeg_data_len) == 0) {
log_char('M');
@@ -230,7 +409,14 @@ static void video_show_task(void *priv)
}
#endif
if (out_fd) { //录像输出
if (!jljpeg_frame_dropping_judge()) {
__this->write_error = AVI_write_frame(out_fd, (char *)jpeg_data, jpeg_data_len, 1);
jljpeg_frame_fill_judge(out_fd, 1); //补帧计算
} else {
jljpeg_frame_fill_judge(out_fd, 0); //补帧计算
}
}
camera_manager_read_done(jpeg_data);
#if 0
@@ -302,7 +488,11 @@ int jlcamera_video_rec_init(void)
{
int ret = 0;
ASSERT(!__this);
__this = zalloc(sizeof(struct video_rec_handle));
__this = malloc(sizeof(struct video_rec_handle));
if (!__this) {
goto __err;
}
memset(__this, 0, sizeof(struct video_rec_handle));
__this->busy = 1;
clock_lock("camera_video", clk_get_max_frequency());
//初始化驱动
@@ -320,8 +510,8 @@ int jlcamera_video_rec_init(void)
//视频帧率
__this->video_rate = fps / 2;
//音频采样率
__this->sample_rate = 8000;
__this->aframe_size = 4096;
__this->sample_rate = MIC_SIMPLE_RATE;
__this->aframe_size = MIC_FREMA_SIZE;
snprintf(__this->avi_task_name, sizeof(__this->avi_task_name), "video_show_task");
if (os_task_create(video_show_task, __this, 8, 1024, 1024, __this->avi_task_name)) {
@@ -22,10 +22,8 @@ struct avi_audio_file_handle {
const struct stream_file_ops *file_ops;
};
extern const int OPUS_SRINDEX; // 选择opus解码文件的帧大小,0代表一帧40字节,1代表一帧80字节,2代表一帧160字节
extern u32 bt_audio_conn_clock_time(void *addr);
extern cbuffer_t avi_pcm_cbuf;
extern OS_MUTEX avi_pcm_mutex;
static int avi_fseek(void *_hdl, u32 fpos)
{
@@ -77,17 +75,14 @@ static enum stream_node_state avi_audio_get_frame(void *file, struct stream_fram
#if TCFG_VIDEO_DIAL_ENABLE // avi 音频pcm数据读取
if (get_avi_audio_status()) {
os_mutex_pend(&avi_pcm_mutex, 0);
u32 data_len = cbuf_get_data_size(&avi_pcm_cbuf);
// printf("[cbuf_get_data_size] data_len:%d\n", data_len);
if (data_len >= fram_len) {
cbuf_read(&avi_pcm_cbuf, frame->data, fram_len);
// printf("[cbuf_read] fram_len:%d\n", fram_len);
os_mutex_post(&avi_pcm_mutex);
frame->len = fram_len;
// printf("[avi_audio_get_frame] frame->len:%d\n", frame->len);
} else {
os_mutex_post(&avi_pcm_mutex);
// puts("silent audio data\n");
memset(frame->data, 0, fram_len); // 数据不足时填零静音
frame->len = 0;//fram_len;
@@ -128,28 +123,12 @@ static void avi_audio_tick_handler(void *priv, u8 source)
static int avi_audio_file_get_fmt(struct avi_audio_file_handle *hdl, struct stream_fmt *fmt)
{
#if 0
fmt->coding_type = AUDIO_CODING_OPUS;
fmt->sample_rate = 16000;
fmt->channel_mode = AUDIO_CH_MIX;
#else
extern const int CONFIG_OGG_OPUS_DEC_SUPPORT;
#if TCFG_DEC_OGG_OPUS_ENABLE
if (CONFIG_OGG_OPUS_DEC_SUPPORT) {
fmt->sample_rate = 48000;
}
return hdl->file_ops->get_fmt(hdl->file, fmt);
#else
fmt->coding_type = hdl->param.coding_type;
fmt->sample_rate = hdl->param.sample_rate;
fmt->channel_mode = hdl->param.channel_mode;
fmt->frame_dms = hdl->param.frame_dms;
fmt->bit_rate = hdl->param.bit_rate;
printf("%s 0x%x, %d, %d, %d, %d\n", __FUNCTION__, fmt->coding_type, fmt->sample_rate, fmt->channel_mode, fmt->frame_dms, fmt->bit_rate);
#endif
#endif
return 0;
}
@@ -218,12 +197,7 @@ static void avi_audio_file_release(void *file)
REGISTER_SOURCE_NODE_PLUG(avi_audio_file_plug) = {
.uuid = NODE_UUID_VIDEO_DEC,
.init = avi_audio_file_init,
#if TCFG_DEC_OGG_OPUS_ENABLE
.read = avi_fread,
.seek = avi_fseek,
#else
.get_frame = avi_audio_get_frame,
#endif
.ioctl = avi_audio_file_ioctl,
.release = avi_audio_file_release,
};
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,7 @@
{
"-name": "BT_Watch",
"-type": "project",
"activePage": 84,
"activePage": 83,
"chip_type": "BR35",
"dpi_type": "72",
"lang_excel": "../../多国语言/多国语言_watch.xls",
@@ -1425,7 +1425,7 @@
"height": 89,
"width": 320,
"x": 0,
"y": -86
"y": 0
}
},
{
@@ -1988,7 +1988,7 @@
"height": 89,
"width": 320,
"x": 0,
"y": 9
"y": 95
}
},
{
@@ -2551,7 +2551,7 @@
"height": 89,
"width": 320,
"x": 0,
"y": 104
"y": 190
}
},
{
@@ -3114,7 +3114,7 @@
"height": 89,
"width": 320,
"x": 0,
"y": 199
"y": 285
}
},
{
@@ -3677,7 +3677,7 @@
"height": 89,
"width": 320,
"x": 0,
"y": 294
"y": 380
}
},
{
@@ -429875,7 +429875,7 @@
{
"-name": "background_color",
"-type": "background-color",
"background-color": "",
"background-color": "#ff000000",
"caption": "背景颜色"
},
{
@@ -432353,7 +432353,7 @@
"-name": "invisible",
"-type": "enum",
"caption": "默认隐藏",
"default": "false",
"default": "true",
"enum": [
{
"true": 1
@@ -435281,7 +435281,7 @@
{
"-name": "background_color",
"-type": "background-color",
"background-color": "",
"background-color": "#ff000000",
"caption": "背景颜色"
},
{
@@ -438837,7 +438837,7 @@
{
"-name": "background_color",
"-type": "background-color",
"background-color": "",
"background-color": "#ff000000",
"caption": "背景颜色"
},
{
@@ -445822,9 +445822,9 @@
"-type": "text-pic",
"caption": "文字列表",
"compress": true,
"default": "M607",
"default": "M633",
"list": [
"M607"
"M633"
],
"maxlength": 100,
"text_type": "default"
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -850,8 +850,6 @@ void *cache_gpu_input_jpeg_data(void *head, pJLGPUTaskParam_t task_param, void *
return NULL;
}
//cache
/* u32 jpeg_stride = 2 * (jpg_hd->width + 7) / 8 * 8; */
/* u32 jpeg_height_align = (jpg_hd->height + 7) / 8 * 8; */
u32 jpeg_width_align = (jpg_hd->width + 15) / 16 * 16;
u32 jpeg_stride = 2 * jpeg_width_align;
u32 jpeg_height_align = (jpg_hd->height + 15) / 16 * 16;
@@ -882,6 +880,8 @@ void *cache_gpu_input_jpeg_data(void *head, pJLGPUTaskParam_t task_param, void *
task_param->image.width = (width + 15) / 16 * 16;
task_param->image.height = (height + 15) / 16 * 16;
if (cache_addr) {
gpu_input_stream_cache_vaild_value_set_by_index((u32)cache_addr, 3);
gpu_input_stream_cache_set_index((u32)cache_addr, index);
+108 -3
View File
@@ -27,6 +27,7 @@
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_WARN_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
@@ -61,6 +62,103 @@ struct jpeg_stream_info {
#define GPU_TASK_ID(page, id, index) ((page << 26) | (0 << 24) | (id << 8) | index)
#define JLGPU_TASK_ROTATE_CONFIG(tran) \
{ \
task_param.rotate_en = dc->elm->rotate_en; \
if (task_param.rotate_en && dc->elm->css.part) { \
(tran)->rotate_cx = dc->elm->css.part->rotate.cent_x; \
(tran)->rotate_cy = dc->elm->css.part->rotate.cent_y; \
(tran)->rotate_dx = dc->elm->css.part->rotate.dx; \
(tran)->rotate_dy = dc->elm->css.part->rotate.dy; \
(tran)->rotate_angle = dc->elm->css.part->rotate.angle; \
log_debug("%s(), rotate_en: %d, cx:%d, cy:%d, dx:%d, dy:%d, angle:%f\n", __func__, \
task_param.rotate_en, (tran)->rotate_cx, (tran)->rotate_cy, \
(tran)->rotate_dx, (tran)->rotate_dy, (tran)->rotate_angle); \
} \
}
#define JLGPU_TASK_SCALE_CONFIG(tran) \
{ \
task_param.scale_en = dc->elm->ratio_en; \
if (task_param.scale_en && dc->elm->css.part) { \
(tran)->ratio_w = dc->elm->css.part->ratio.ratio_w; \
(tran)->ratio_h = dc->elm->css.part->ratio.ratio_h; \
log_debug("%s(), scale_en: %d, ratio_w: %f, ratio_h: %f\n", __func__, \
task_param.scale_en, (tran)->ratio_w, (tran)->ratio_h); \
} \
}
#define INHERIT_PARENT_AFFINE(tran) \
{ \
for (; elm; elm = elm->parent) { \
pJLGPUTaskUnit_t task_parent = jlgpu_get_task_by_id(dc->gpu_task_head, JLGPU_ID_NONE, elm->id); \
if (task_parent && task_parent->info.matrix) { \
log_info("%s(), get parent affine! parent elm_id: 0x%x\n", __func__, elm->id); \
task_param.matrix = task_parent->info.matrix; \
struct rect parent_rect = {0}; \
ui_core_get_element_rect_relative_screen(elm, &parent_rect); \
/* ui_core_get_element_rect_relative_parent(elm, &parent_rect); */ \
/* DUMP_RECT(__func__, __LINE__, "parent", &parent_rect); */ \
task_param.draw.left -= (/* parent_rect.left < 0 ? 0 : */ parent_rect.left); \
task_param.draw.top -= (/* parent_rect.top < 0 ? 0 : */ parent_rect.top); \
if (task_param.draw.height <= 0 || task_param.draw.width <= 0) { \
task_param.invisible = true; \
} \
if (task_param.rotate_en) { \
(tran)->rotate_dx -= parent_rect.left; \
(tran)->rotate_dy -= parent_rect.top; \
} \
} \
} \
}
#define JLGPU_TASK_INHERIT_PARENT(tran) \
{ \
if (dc->elm && dc->elm->parent) { \
log_debug("%s(), get parent info!:%x\n", __func__,dc->elm->id); \
struct element *elm = dc->elm->parent; \
struct element *par = elm->parent; \
if ((par) && (ui_id2type(par->id) == CTRL_TYPE_GRID)) { \
elm = par; \
} \
u8 is_overstepping_parent; \
pJLGPUTaskUnit_t task_parent = jlgpu_get_task_by_id(dc->gpu_task_head, JLGPU_ID_NONE, elm->id); \
if (task_parent) { \
is_overstepping_parent = false; \
struct element *elm = ui_core_get_element_by_id(task_parent->info.element_id); \
if (elm) { \
ui_core_get_element_rect_relative_screen(elm, &task_param.area); \
jlgpu_shift_rect(&task_param.area); \
} else { \
jlgpu_get_task_rect(task_parent, &task_param.area); \
} \
} else { \
is_overstepping_parent = true; \
/* ui_core_get_element_abs_rect(elm, &task_param.area); */ \
ui_core_get_element_rect_relative_screen(elm, &task_param.area); \
} \
log_info("%s(), parent area[%d, %d, %d, %d]\n", __func__, \
task_param.area.left, task_param.area.top, task_param.area.width, task_param.area.height); \
INHERIT_PARENT_AFFINE(tran); \
if (task_param.matrix && is_overstepping_parent) { \
gpu_boundbox_t parent_area; \
parent_area.minx = task_param.area.left; \
parent_area.maxx = task_param.area.width + parent_area.minx; \
parent_area.miny = task_param.area.top; \
parent_area.maxy = task_param.area.height + parent_area.miny; \
gpu_matrix_get_boundbox(task_param.matrix, &parent_area, &parent_area); \
task_param.area.left = parent_area.minx; \
task_param.area.width = parent_area.maxx - parent_area.minx; \
task_param.area.top = parent_area.miny; \
task_param.area.height = parent_area.maxy - parent_area.miny; \
} else if (is_overstepping_parent) { \
jlgpu_shift_rect(&task_param.area); \
/* struct lcd_info *lcd_info = &(((struct ui_priv *)__this)->info); */ \
/* task_param.area.left += ((GPU_BOUND_BOX_MAX - lcd_info->width) / 2); */ \
/* task_param.area.top += ((GPU_BOUND_BOX_MAX - lcd_info->height) / 2); */ \
} \
} \
}
extern u32 usr_mmu_hash(u32 hash, u8 *data, int len);
extern void *jpeg_module_opj_create_file(void *path, int path_len, u32 check, u32 index, u32 task_id, u32 elm_id);
@@ -400,7 +498,7 @@ void *cache_gpu_input_jpeg_data_file(void *head, pJLGPUTaskParam_t task_param, u
int jpeg_src_data_len = 0;
log_debug("@@@@@ cache_addr: 0x%x\n crc:0x%x path:%s", (u32)cache_addr, check, path);
if (!cache_addr) {//解码jpeg到psram
log_debug("%s path%s", __func__, path);
printf("%s path%s", __func__, path);
if (strstr(path, "avi") || strstr(path, "AVI")) {
log_debug("AVI");
@@ -544,7 +642,10 @@ void *cache_gpu_input_jpeg_data_file(void *head, pJLGPUTaskParam_t task_param, u
task_param->image.width = (width + 15) / 16 * 16;
task_param->image.height = (height + 15) / 16 * 16;
task_param->crop_en = ((task_param->image.width != width)
|| (task_param->image.height != height)) ? 1 : 0;
task_param->texture.crop.width = width;
task_param->texture.crop.height = height;
if (cache_addr) {
gpu_input_stream_cache_vaild_value_set_by_index((u32)cache_addr, 3);
}
@@ -609,8 +710,12 @@ int jpeg_image_file_psram(struct draw_context *dc, int left, int top, int width,
task_param.scale_en = scale_en;
task_param.texture.tran.ratio_w = scale_f;
task_param.texture.tran.ratio_h = scale_f;
/* 继承父控件变换 */
JLGPU_TASK_INHERIT_PARENT(&task_param.fill.tran);
if (task_param.texture.data) {
jlgpu_update_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id, &task_param);
pJLGPUTaskUnit_t taskp = jlgpu_update_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id, &task_param);
/* jlgpu_dump_task_info(taskp,0); */
}
return 0;
}
@@ -40,7 +40,7 @@
#define LCD_W LCD_WIDTH
#define LCD_H LCD_HEIGHT
#define LCD_BLOCK_W LCD_WIDTH
#define LCD_BLOCK_H 20
#define LCD_BLOCK_H 16
#define BUF_NUM 2
#define LCD_FORMAT OUTPUT_FORMAT_RGB565