1、同步BR28。add 文件传输crc校验心跳包,防止传输大文件校验超时;
2、修正科大讯飞、摄像头测试问题;
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
+26
-1
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
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,33 +427,37 @@ 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 (!ifly_vad_is_work()) {
|
||||
// 开始
|
||||
if (ifly_check_net_connect() == false) {
|
||||
UI_MSG_POST("vad_network_no_connect");
|
||||
break;
|
||||
}
|
||||
ui_hide(IFLY_LAYOUT_VAD);
|
||||
ui_show(IFLY_LAYOUT_CONNECTTING);
|
||||
if (!ui_ifly_vad_button_get_touch()) {
|
||||
if (!ifly_vad_is_work()) {
|
||||
// 开始
|
||||
if (ifly_check_net_connect() == false) {
|
||||
UI_MSG_POST("vad_network_no_connect");
|
||||
break;
|
||||
}
|
||||
ui_hide(IFLY_LAYOUT_VAD);
|
||||
ui_show(IFLY_LAYOUT_CONNECTTING);
|
||||
|
||||
ifly_vad_stop(1, 10);
|
||||
p_ifly_net->vad_param.vad_res = p_ifly_net->local_text;
|
||||
p_ifly_net->vad_param.vad_res_len = MAX_VAD_LEN;
|
||||
p_ifly_net->vad_param.event_cb = ui_ifly_vad_event_cb;
|
||||
p_ifly_net->vad_param.vad_res[0] = 0;
|
||||
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);
|
||||
ifly_vad_stop(1, 10);
|
||||
p_ifly_net->vad_param.vad_res = p_ifly_net->local_text;
|
||||
p_ifly_net->vad_param.vad_res_len = MAX_VAD_LEN;
|
||||
p_ifly_net->vad_param.event_cb = ui_ifly_vad_event_cb;
|
||||
p_ifly_net->vad_param.vad_res[0] = 0;
|
||||
ifly_vad_start(&p_ifly_net->vad_param);
|
||||
} else {
|
||||
// 停止
|
||||
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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(¶m, &(__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(¶m, &(__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(¶m, &(__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,17 +1765,17 @@ 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;
|
||||
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); */
|
||||
if (w == 0) {
|
||||
os_time_dly(1);
|
||||
continue;
|
||||
if (__this->param.is_audio_mute != 1) {
|
||||
while (len) {
|
||||
u32 w = cbuf_write(&avi_pcm_cbuf, ptr, len); // 直接按len写,返回实际写入
|
||||
/* log_info("[cbuf_write] w:%d len=%d\n", w, len); */
|
||||
if (w == 0) {
|
||||
os_time_dly(1);
|
||||
continue;
|
||||
}
|
||||
ptr += w;
|
||||
len -= w;
|
||||
}
|
||||
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");
|
||||
avi_pcm_close(md->st);
|
||||
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), ¶m, 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");
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) { //录像输出
|
||||
__this->write_error = AVI_write_frame(out_fd, (char *)jpeg_data, jpeg_data_len, 1);
|
||||
|
||||
|
||||
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)) {
|
||||
|
||||
Reference in New Issue
Block a user