修复摄像头、科大讯飞、rcsp、彩屏仓等相关测试问题;
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#include "clock_manager/clock_manager.h"
|
||||
#include "product_test.h"
|
||||
#include "chgbox_ctrl.h"
|
||||
#include "app_video.h"
|
||||
|
||||
#define LOG_TAG "[APP]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
@@ -767,7 +768,12 @@ static void app_task_loop(void *p)
|
||||
mode = app_enter_rcsp_mode(g_mode_switch_arg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if TCFG_APP_VIDEO_EN
|
||||
case APP_MODE_VIDEO:
|
||||
log_info("APP_MODE_VIDEO \n");
|
||||
mode = app_enter_video_mode(g_mode_switch_arg);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -673,7 +673,14 @@
|
||||
//camera
|
||||
#define TCFG_CAMERA_MANAGER_ENABLE 0//相机、相册、摄像头功能
|
||||
#define TCFG_CAMERA_DEV_BF30A2 0//摄像头驱动bf30a2
|
||||
#if TCFG_VIDEO_DIAL_ENABLE || TCFG_CAMERA_MANAGER_ENABLE
|
||||
#define TCFG_APP_VIDEO_EN 1
|
||||
#endif
|
||||
|
||||
//*********************************************************************************//
|
||||
// USB配置 //
|
||||
//*********************************************************************************//
|
||||
// #define TCFG_OTG_MODE 0
|
||||
//*********************************************************************************//
|
||||
// 产测配置 //
|
||||
//*********************************************************************************//
|
||||
|
||||
@@ -21,6 +21,7 @@ enum app_mode_t {
|
||||
APP_MODE_SPDIF = 11,
|
||||
APP_MODE_RCSP = 12,
|
||||
APP_MODE_SMARTBOX = 13,
|
||||
APP_MODE_VIDEO = 14,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef CONFIG_APP_VIDEO_H
|
||||
#define CONFIG_APP_VIDEO_H
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
struct app_mode *app_enter_video_mode(int arg);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -734,6 +734,9 @@
|
||||
//*********************************************************************************//
|
||||
// VIDEO CONFIG //
|
||||
//*********************************************************************************//
|
||||
#ifndef TCFG_APP_VIDEO_EN
|
||||
#define TCFG_APP_VIDEO_EN DISABLE
|
||||
#endif
|
||||
#ifndef TCFG_VIDEO_DIAL_ENABLE
|
||||
#define TCFG_VIDEO_DIAL_ENABLE DISABLE
|
||||
#endif
|
||||
|
||||
@@ -562,6 +562,7 @@
|
||||
#define BASEFORM_1355 0XA61000
|
||||
#define BASEFORM_1356 0XA60C00
|
||||
#define BASEFORM_1357 0XA63000
|
||||
#define BASEFORM_1358 0XA83002
|
||||
#define BASEFORM_1359 0X7C0C0D
|
||||
#define BASEFORM_136 0X4A3C12
|
||||
#define BASEFORM_1360 0X7C3002
|
||||
@@ -1724,6 +1725,17 @@
|
||||
#define DISCONN_QR_BUTTON 0X303004
|
||||
#define DISCONN_QR_LAYOUT 0X300C01
|
||||
#define DISCONN_YES_BUTTON 0X302001
|
||||
#define DUER_BASEFORM_ERROR 0XA80C00
|
||||
#define DUER_BASEFORM_RECORD 0XA80C03
|
||||
#define DUER_BASEFORM_RESPONSE 0XA80C01
|
||||
#define DUER_BASEFORM_THINK 0XA80C02
|
||||
#define DUER_ERROR_NOTE 0XA83000
|
||||
#define DUER_RECORD_BUTTON 0XA81C00
|
||||
#define DUER_RECORD_TIME 0XA83C00
|
||||
#define DUER_RECORD_TXT 0XA83003
|
||||
#define DUER_RESPONSE_TTS 0XA82000
|
||||
#define DUER_RESPONSE_TXT 0XA83001
|
||||
#define DUER_THINKING 0XA82001
|
||||
#define ENGINEERING_MODE_VLIST 0X8A1400
|
||||
#define FACE_INDEX 0X803C00
|
||||
#define FINDMY_BINDING 0X942002
|
||||
@@ -1767,6 +1779,7 @@
|
||||
#define IFLY_TIME_VAD 0XA03C00
|
||||
#define INDOOR_SPORT_LAYOUT 0X580C00
|
||||
#define INDOOR_SPORT_LIST 0X581400
|
||||
#define INTELLIGENT_DUER_LAYER 0XA81000
|
||||
#define LAYER_WOMEN_HEALTH 0X4A1000
|
||||
#define LAYOUT_MENU_WATERFALL 0X480C00
|
||||
#define LAYOUT_UVC_SHOW 0XA20C00
|
||||
@@ -2000,6 +2013,7 @@
|
||||
#define PAGE_81 0XA20851
|
||||
#define PAGE_82 0XA40852
|
||||
#define PAGE_83 0XA60853
|
||||
#define PAGE_84 0XA80854
|
||||
#define PAGE_9 0X120809
|
||||
#define PASSWORD_0_BUTTON 0X162010
|
||||
#define PASSWORD_1_BUTTON 0X162007
|
||||
@@ -2554,7 +2568,7 @@
|
||||
#define TIME_UNDISTURB_MODE_START_TIME 0X102800
|
||||
#define TRANSIT_LOADING_PIC 0X22200C
|
||||
#define UI_ROTATE 0X0
|
||||
#define UI_VERSION 0X3E18F271
|
||||
#define UI_VERSION 0X74A92D3
|
||||
#define UNDISTURB_MODE_ESETTING_BACK_BUTTON 0X102004
|
||||
#define UNDISTURB_MODE_ESETTING_HOUR_VLIST 0X101401
|
||||
#define UNDISTURB_MODE_ESETTING_LAYOUT 0X100C05
|
||||
|
||||
@@ -59,16 +59,25 @@ const int ENABLE_PSRAM_UI_FRAME = 0; //psram特效,暂不使用
|
||||
const int JLUI_CORE_GRID_KEY_VER = 0x1; //列表编码器转动版本
|
||||
const int UI_NANDFLASH_RES_BY_PACKRES = TCFG_NANDFLASH_UI_FAT_ENABLE; //使用标准fat+packres打包资源
|
||||
const int UI_CORE_FOCUS_FILTER_ENABLE = 1;
|
||||
|
||||
|
||||
const int config_jpeg_isr_delay_us = 50; //参考值100,最小50
|
||||
const int JLJPEG_STREAM_ENABLE = 1;
|
||||
const int config_jpeg_sync_wait_in_irq = 0; //在中断同步等待
|
||||
#if CONFIG_DOUBLE_BANK_ENABLE
|
||||
const int UI_RES_FLASH_TAB_OFFSET = 0x20; //双备份内置资源偏移
|
||||
#else
|
||||
const int UI_RES_FLASH_TAB_OFFSET = 0x0;
|
||||
#endif
|
||||
//================================================//
|
||||
// JPEG //
|
||||
//================================================//
|
||||
const int config_jpeg_isr_delay_us = 50; //参考值100,最小50
|
||||
const int JLJPEG_STREAM_ENABLE = 1;
|
||||
#if TCFG_HOST_UVC_ENABLE
|
||||
const int config_jpeg_sync_wait_in_irq = 1; //在中断同步等待,效率低
|
||||
const int config_jpeg_ff_rst_enable = 1; //支持带DRI标志的图片,部分摄像头只输出这种类型的图片
|
||||
#else
|
||||
const int config_jpeg_sync_wait_in_irq = 0; //在中断同步等待
|
||||
const int config_jpeg_ff_rst_enable = 0; //支持带DRI标志的图片,非UVC功能不开,由app等转码。带DRI标志解码效率低
|
||||
#endif
|
||||
const int config_jpeg_pend_timeout = 20; //
|
||||
|
||||
//================================================//
|
||||
// GPU中断 //
|
||||
//================================================//
|
||||
@@ -97,7 +106,11 @@ const int KHMER_MODE_SWITCH = 0;
|
||||
const int INDIC_MODE_SWITCH = 0;
|
||||
const int TIBETAN_MODE_SWITCH = 0;
|
||||
const int MIXLEFT_MODE_SWITCH = 0;
|
||||
#if TCFG_IFLYTEK_ENABLE
|
||||
const int MIXRIGHT_MODE_SWITCH = 1;
|
||||
#else
|
||||
const int MIXRIGHT_MODE_SWITCH = 0;
|
||||
#endif
|
||||
const int FONT_UNIC_SWITCH = 1;
|
||||
const int FONT_USE_PTR = !TCFG_NANDFLASH_DEV_ENABLE;
|
||||
const int SCALE_EFFECT_WITHOUT_PSRAM_ENABLE = 0;
|
||||
@@ -115,7 +128,7 @@ const u32 config_ui_alloc_psram_mod_sel = \
|
||||
BIT(UI_MODULE_RESOURCE) | \
|
||||
BIT(UI_MODULE_GPU) | \
|
||||
BIT(UI_MODULE_FONT) | \
|
||||
BIT(UI_MODULE_JPEG) | \
|
||||
/* BIT(UI_MODULE_JPEG) | \ */ \
|
||||
BIT(UI_MODULE_CACHE) | \
|
||||
BIT(UI_MODULE_CUSTOM_DRAW);
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".video.data.bss")
|
||||
#pragma data_seg(".video.data")
|
||||
#pragma const_seg(".video.text.const")
|
||||
#pragma code_seg(".video.text")
|
||||
#endif
|
||||
#include "system/includes.h"
|
||||
#include "app_main.h"
|
||||
#include "app_video.h"
|
||||
#include "ui/ui_api.h"
|
||||
|
||||
#define LOG_TAG "[APP_VIDEO]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if TCFG_APP_VIDEO_EN
|
||||
|
||||
extern u8 get_avi_audio_status();
|
||||
|
||||
|
||||
static int app_video_init()
|
||||
{
|
||||
log_info("%s", __func__);
|
||||
|
||||
app_send_message(APP_MSG_ENTER_MODE, APP_MODE_VIDEO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void app_video_exit()
|
||||
{
|
||||
static int count = 0;
|
||||
log_info("%s", __func__);
|
||||
|
||||
UI_MSG_POST("video_show_exit");
|
||||
while (get_avi_audio_status() && count < 30) {
|
||||
++count;
|
||||
os_time_dly(10);
|
||||
}
|
||||
count = 0;
|
||||
app_send_message(APP_MSG_EXIT_MODE, APP_MODE_VIDEO);
|
||||
}
|
||||
|
||||
struct app_mode *app_enter_video_mode(int arg)
|
||||
{
|
||||
int msg[16];
|
||||
struct app_mode *next_mode;
|
||||
|
||||
app_video_init();
|
||||
|
||||
while (1) {
|
||||
if (!app_get_message(msg, ARRAY_SIZE(msg), NULL)) {
|
||||
continue;
|
||||
}
|
||||
next_mode = app_mode_switch_handler(msg);
|
||||
if (next_mode) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (msg[0]) {
|
||||
case MSG_FROM_APP:
|
||||
break;
|
||||
case MSG_FROM_DEVICE:
|
||||
break;
|
||||
}
|
||||
|
||||
app_default_msg_handler(msg);
|
||||
}
|
||||
|
||||
app_video_exit();
|
||||
|
||||
return next_mode;
|
||||
}
|
||||
|
||||
static int video_mode_try_enter(int arg)
|
||||
{
|
||||
log_info("%s", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int video_mode_try_exit()
|
||||
{
|
||||
log_info("%s", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct app_mode_ops video_mode_ops = {
|
||||
.try_enter = video_mode_try_enter,
|
||||
.try_exit = video_mode_try_exit,
|
||||
};
|
||||
|
||||
/*
|
||||
* 注册video模式
|
||||
*/
|
||||
REGISTER_APP_MODE(video_mode) = {
|
||||
.name = APP_MODE_VIDEO,
|
||||
.index = 0xff,
|
||||
.ops = &video_mode_ops,
|
||||
};
|
||||
|
||||
#endif /*TCFG_APP_VIDEO_EN*/
|
||||
@@ -1,4 +1,4 @@
|
||||
.section .sys.version, "ax"
|
||||
|
||||
.long 313049334
|
||||
.asciz "-@20251202-$410e8ade"
|
||||
.long 313673739
|
||||
.asciz "-@20251209-$fa0a9cb7"
|
||||
|
||||
@@ -137,7 +137,9 @@ static int ai_text_rx_cb(u8 ai_text, u8 *data, int len)
|
||||
// UTF8
|
||||
ai_txttempa = tts_txt;
|
||||
ai_txttempb = ai_txt2;
|
||||
UI_MSG_POST("SEND_TXT");
|
||||
if (ai_text) {
|
||||
UI_MSG_POST("SEND_TXT");
|
||||
}
|
||||
log_i("rx text:%d, %s \n", ai_text, data);
|
||||
put_buf(data, len);
|
||||
return false;
|
||||
|
||||
@@ -447,6 +447,8 @@ static void ai_txt_empty_handler(void *priv)
|
||||
char empty_str_copy[50] = "您好像并没有说话";
|
||||
strcpy(empty_str, empty_str_copy);
|
||||
ui_text_set_textu_by_id(AI_DIAL_TXT, (char *)empty_str, strlen((char *)empty_str), FONT_DEFAULT | FONT_SHOW_MULTI_LINE);
|
||||
} else {
|
||||
ui_text_set_textu_by_id(AI_DIAL_TXT, (char *)ai_dial_txt1, strlen((char *)ai_dial_txt1), FONT_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,6 +687,30 @@ static int AI_dialogue_ontouch(void *ctr, struct element_touch_event *e)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static int AI_dial_time_onchange(void *ctr, enum element_change_event e, void *arg)
|
||||
{
|
||||
struct ui_number *ui_num = (struct ui_number *)ctr;
|
||||
struct unumber num;
|
||||
switch (e) {
|
||||
case ON_CHANGE_INIT:
|
||||
cuntdown_flag = 60;
|
||||
num.type = TYPE_NUM;
|
||||
num.numbs = 1;
|
||||
num.number[0] = cuntdown_flag;
|
||||
ui_number_update(ui_num, &num);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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,
|
||||
@@ -696,6 +722,12 @@ REGISTER_UI_EVENT_HANDLER(AI_DIAL_VOICE)
|
||||
.onkey = NULL,
|
||||
.ontouch = AI_dialogue_ontouch,
|
||||
};
|
||||
REGISTER_UI_EVENT_HANDLER(AI_DIAL_TIME)
|
||||
.onchange = AI_dial_time_onchange,
|
||||
.onkey = NULL,
|
||||
.ontouch = NULL,
|
||||
};
|
||||
|
||||
//****************************************************************************************/
|
||||
// layout3-AI表盘 //
|
||||
/****************************************************************************************/
|
||||
|
||||
@@ -128,8 +128,10 @@ void camera_dec_reflush_sync(int status)
|
||||
int msg[3] = {0};
|
||||
|
||||
if (!status) {
|
||||
//正常刷新
|
||||
msg[0] = (int)camera_dec_flush;
|
||||
} else {
|
||||
//异常显示
|
||||
msg[0] = (int) camera_rec_err;
|
||||
}
|
||||
msg[1] = 1;
|
||||
@@ -178,6 +180,9 @@ static int cam_ctrl_view_video(int enable)
|
||||
}
|
||||
static void cam_camera_photo_savc_cb(char *path)
|
||||
{
|
||||
if (jljpeg_stream_src_data_get()) {
|
||||
return;
|
||||
}
|
||||
jljpeg_stream_src_data_save_to_file(path);
|
||||
if (__this && (__this->photo_save_cnt > 0)) {
|
||||
__this->photo_save_cnt--;
|
||||
@@ -357,6 +362,29 @@ static int cam_handler_prepare_cb(void *ctrl, int count, int start)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//****************************************************************************************//
|
||||
// 消息处理
|
||||
//****************************************************************************************//
|
||||
static int ui_video_show_exit_handler(const char *type, u32 arg)
|
||||
{
|
||||
log_info("[%s]", __func__);
|
||||
|
||||
switch (__this->layout_curr) {
|
||||
case CAM_SHOW_LAYOUT:
|
||||
cam_layout_sw(CAM_PHOTO_LAYOUT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct uimsg_handl ui_msg_handler[] = {
|
||||
{ "video_show_exit", ui_video_show_exit_handler },
|
||||
{ NULL, NULL}, /* 必须以此结尾! */
|
||||
};
|
||||
|
||||
//****************************************************************************************//
|
||||
// 提醒
|
||||
//****************************************************************************************//
|
||||
@@ -390,6 +418,7 @@ static int cam_layer_onchange(void *ctrl, enum element_change_event event, void
|
||||
//图层初始化变量
|
||||
/* f_format("sd0","fat",0); */
|
||||
cam_ctrl_init();
|
||||
ui_register_msg_handler(ID_WINDOW_CAMERA, ui_msg_handler);
|
||||
break;
|
||||
case ON_CHANGE_RELEASE:
|
||||
cam_ctrl_deinit();
|
||||
@@ -522,6 +551,10 @@ static int cam_camera_layout_onchange(void *ctrl, enum element_change_event even
|
||||
jljpeg_stream_src_data_len_get());
|
||||
break;
|
||||
case ON_CHANGE_RELEASE:
|
||||
if (__this->video_doing) {
|
||||
jlcamera_video_rec_stop();
|
||||
__this->video_doing = 0;
|
||||
}
|
||||
//关闭摄像头
|
||||
jlcamera_video_rec_deinit();
|
||||
//关闭jpeg数据流解码
|
||||
@@ -817,6 +850,8 @@ static int cam_photo_list_ontouch(void *_ctrl, struct element_touch_event *e)
|
||||
if (__this->view_remap[i] == dyn_idx) {
|
||||
if (!__this->view_vaild[i]) {
|
||||
return true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -912,7 +947,88 @@ static void avi_flush_timer(void *p)
|
||||
jlgpu_scheduler_wait_sync();
|
||||
}
|
||||
void __jpeg_draw_cb_gpu(int id, u8 *dst_buf, struct rect *dst_r, struct rect *src_r, u8 bytes_per_pixel, void *priv, void *matrix);
|
||||
static void camera_video_dec_flush(void)
|
||||
{
|
||||
struct element *elm;
|
||||
elm = ui_core_get_element_by_id(CAM_SHOW_LAYOUT);
|
||||
if (elm != NULL) {
|
||||
/* printf(">>>>>>elm != NULL"); */
|
||||
ui_redraw(CAM_SHOW_LAYOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void video_dec_reflush_sync(int status)
|
||||
{
|
||||
void jlui_malloc_ram_info_dump();
|
||||
/* jlui_malloc_ram_info_dump(); */
|
||||
log_debug("%s status:%d !!\n", __func__, status);
|
||||
|
||||
int msg[3] = {0};
|
||||
|
||||
if (!status) {
|
||||
//正常刷新
|
||||
msg[0] = (int) camera_video_dec_flush;
|
||||
} else {
|
||||
//异常显示
|
||||
}
|
||||
msg[1] = 1;
|
||||
msg[2] = 0;
|
||||
int ret = os_taskq_post_type("ui", Q_CALLBACK, 3, msg);
|
||||
}
|
||||
|
||||
#if 0//使用video_dec解码测试.
|
||||
|
||||
extern int video_dec_init();
|
||||
extern int video_dec_deinit();
|
||||
extern int video_dec_set_path(s8(*path)[64], u8 path_number);
|
||||
extern int video_dec_start(u8 index, u8 mode);
|
||||
extern int video_dec_refresh_cb_register(void (*cb)(int status));
|
||||
extern int video_dec_stop();
|
||||
static int cam_show_layout_onchange(void *ctrl, enum element_change_event event, void *arg)
|
||||
{
|
||||
struct ui_grid *grid = (struct ui_grid *)ctrl;
|
||||
struct element *elm = (struct element *)ctrl;
|
||||
struct draw_context *dc = (struct draw_context *)arg;
|
||||
switch (event) {
|
||||
case ON_CHANGE_INIT:
|
||||
if (!__this->sel_path) {
|
||||
break;
|
||||
}
|
||||
if (__this->view_video) {
|
||||
video_dec_init();
|
||||
video_dec_refresh_cb_register(video_dec_reflush_sync);
|
||||
video_dec_set_path((s8(*)[64])__this->sel_path, 1);
|
||||
video_dec_start(0, 0);
|
||||
}
|
||||
break;
|
||||
case ON_CHANGE_SHOW_POST:
|
||||
if (!__this->sel_path) {
|
||||
break;
|
||||
}
|
||||
ui_custom_draw_clear(dc);
|
||||
if (__this->view_video) {
|
||||
//实时显示画面
|
||||
if (!jljpeg_stream_src_data_len_get()) {
|
||||
//码流数据为空时不显示
|
||||
break;
|
||||
}
|
||||
jpeg_image_ram(dc, 40, 0, 240, 320,
|
||||
jljpeg_stream_src_data_get(),
|
||||
jljpeg_stream_src_data_len_get());
|
||||
}
|
||||
break;
|
||||
case ON_CHANGE_RELEASE:
|
||||
video_dec_stop();
|
||||
video_dec_deinit();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cam_show_layout_onchange1(void *ctrl, enum element_change_event event, void *arg)
|
||||
{
|
||||
struct ui_grid *grid = (struct ui_grid *)ctrl;
|
||||
struct element *elm = (struct element *)ctrl;
|
||||
@@ -935,11 +1051,11 @@ static int cam_show_layout_onchange(void *ctrl, enum element_change_event event,
|
||||
if (!get_aviplay_handle()) {
|
||||
break;
|
||||
}
|
||||
/* u16 timer_id = 0; */
|
||||
/* if (!avi_get_avi_playtimer_id()) { */
|
||||
/* timer_id = sys_timeout_add((void *)elm->id, (avi_flush_timer), 10); // 强制满帧刷新 */
|
||||
/* avi_set_avi_playtimer_id(timer_id); */
|
||||
/* } */
|
||||
u16 timer_id = 0;
|
||||
if (!avi_get_avi_playtimer_id()) {
|
||||
timer_id = sys_timeout_add((void *)elm->id, (avi_flush_timer), 10); // 强制满帧刷新
|
||||
avi_set_avi_playtimer_id(timer_id);
|
||||
}
|
||||
u32 avip = (u32)get_avi_player_st_handle();
|
||||
log_debug("player->st %x %d %d ", avip, avi_get_width(get_avi_player_st_handle()), avi_get_height(get_avi_player_st_handle()));
|
||||
ui_draw(dc,
|
||||
@@ -970,9 +1086,9 @@ static int cam_show_layout_onchange(void *ctrl, enum element_change_event event,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
REGISTER_UI_EVENT_HANDLER(CAM_SHOW_LAYOUT)
|
||||
.onchange = cam_show_layout_onchange,
|
||||
/* .onchange = cam_show_layout_onchange, */
|
||||
.onchange = cam_show_layout_onchange1,
|
||||
.onkey = NULL,
|
||||
.ontouch = NULL,
|
||||
};
|
||||
|
||||
@@ -165,6 +165,11 @@ static int show_onchange(void *ctr, enum element_change_event e, void *arg)
|
||||
{
|
||||
switch (e) {
|
||||
case ON_CHANGE_INIT:
|
||||
struct unumber num;
|
||||
num.type = TYPE_NUM;
|
||||
num.numbs = 1;
|
||||
num.number[0] = 20;
|
||||
ui_number_update_by_id(AI_TIME, &num);
|
||||
send_0X09_ENTER();
|
||||
break;
|
||||
case ON_CHANGE_FIRST_SHOW:
|
||||
@@ -254,6 +259,7 @@ static void AI_time1_handler(void *priv)//20秒倒计时,不息屏
|
||||
if (i_flag == 0) { //20倒计时结束后,超时标志位置1
|
||||
i_flag = 20;
|
||||
ai_timeout = true;
|
||||
ui_text_show_index_by_id(AI_TEXT, 0);
|
||||
} else if (flag_button == 0) { //按钮控件按下,开始录音倒计时
|
||||
i_flag = 20;
|
||||
}
|
||||
@@ -391,7 +397,7 @@ static void AI_thinking_handler(void *priv)
|
||||
ui_core_redraw(pic);
|
||||
}
|
||||
flag++;
|
||||
if (flag == 25) { //等待5秒没有获得信号,切到列表
|
||||
if (flag == 100) { //等待5秒没有获得信号,切到列表
|
||||
flag = 0;
|
||||
page_showtxt();
|
||||
}
|
||||
@@ -480,10 +486,10 @@ static void reflash_gettxt_handler(void *priv)
|
||||
static void reflash_gettxtII_handler(void *priv)
|
||||
{
|
||||
if (ai_txt1) {
|
||||
ui_text_set_textu_by_id(AI_TXT1, (char *)ai_txt1, strlen((char *)ai_txt1), FONT_DEFAULT | FONT_SHOW_SCROLL);
|
||||
ui_text_set_textu_by_id(AI_TXT1, (char *)ai_txt1, strlen((char *)ai_txt1), FONT_DEFAULT);
|
||||
} else {
|
||||
ai_txt1 = NULL;
|
||||
ui_text_set_textu_by_id(AI_TXT1, (char *)ai_txt1, 0, FONT_DEFAULT | FONT_SHOW_SCROLL);
|
||||
ui_text_set_textu_by_id(AI_TXT1, (char *)ai_txt1, 0, FONT_DEFAULT);
|
||||
}
|
||||
}
|
||||
void memset_txt(void)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "vad_main.h"
|
||||
#include "ifly_socket.h"
|
||||
#include "cat1/cat1_common.h"
|
||||
#include "font/language_list.h"
|
||||
|
||||
#if TCFG_IFLYTEK_ENABLE //科大讯飞网络版
|
||||
|
||||
@@ -45,6 +46,7 @@
|
||||
|
||||
// ui参数
|
||||
struct ifly_ui_t {
|
||||
u8 net_fail;
|
||||
u16 time_id; // 定时器
|
||||
u16 task_create_timer;
|
||||
u16 switch_pic_cnt; // 动图循环
|
||||
@@ -184,12 +186,18 @@ REGISTER_UI_EVENT_HANDLER(IFLY_BUTTON_TTS_PLAY)
|
||||
|
||||
static void reflash_gettxt_handler(void *priv)
|
||||
{
|
||||
if (ifly_check_net_connect() == false) {
|
||||
u8 *net_fail = (u8 *)priv;
|
||||
if (ifly_check_net_connect() == false && !(*net_fail)) {
|
||||
UI_MSG_POST("tts_network_no_connect");
|
||||
}
|
||||
|
||||
ui_auto_shut_down_re_run();
|
||||
|
||||
font_lang_set(UnicodeMixRightword);
|
||||
ui_text_set_textu_by_id(AI_4,
|
||||
p_ifly_net->local_text, strlen(p_ifly_net->local_text),
|
||||
FONT_DEFAULT | FONT_SHOW_MULTI_LINE);
|
||||
|
||||
ui_text_set_textu_by_id(IFLY_TEXT_TTS_TXT,
|
||||
p_ifly_net->ai_text, strlen(p_ifly_net->ai_text),
|
||||
FONT_DEFAULT | FONT_SHOW_MULTI_LINE | FONT_VERTICAL_SCROLL);
|
||||
@@ -217,7 +225,12 @@ static int showtxt_onchange(void *ctr, enum element_change_event e, void *arg)
|
||||
sys_timer_del(ifly_ui->time_id);
|
||||
ifly_ui->time_id = 0;
|
||||
}
|
||||
ifly_ui->time_id = sys_timer_add(NULL, reflash_gettxt_handler, 1000);
|
||||
if (ifly_check_net_connect()) {
|
||||
ifly_ui->net_fail = 0;
|
||||
} else {
|
||||
ifly_ui->net_fail = 1;
|
||||
}
|
||||
ifly_ui->time_id = sys_timer_add((void *)&ifly_ui->net_fail, reflash_gettxt_handler, 1000);
|
||||
break;
|
||||
case ON_CHANGE_FIRST_SHOW:
|
||||
break;
|
||||
@@ -502,6 +515,26 @@ REGISTER_UI_EVENT_HANDLER(IFLY_LAYOUT_VAD)
|
||||
.ontouch = NULL,
|
||||
};
|
||||
|
||||
static int no_connect_ontouch(void *ctr, struct element_touch_event *e)
|
||||
{
|
||||
switch (e->event) {
|
||||
case ELM_EVENT_TOUCH_R_MOVE:
|
||||
if (ifly_ui && ifly_ui->cur_layout) {
|
||||
ui_hide(IFLY_LAYOUT_NO_CONNECT);
|
||||
ui_show(ifly_ui->cur_layout);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
REGISTER_UI_EVENT_HANDLER(IFLY_LAYOUT_NO_CONNECT)
|
||||
.onchange = NULL,
|
||||
.onkey = NULL,
|
||||
.ontouch = no_connect_ontouch,
|
||||
};
|
||||
|
||||
static void ifly_no_content_time_deal(void *priv)
|
||||
{
|
||||
|
||||
@@ -87,6 +87,7 @@ static int uvc_layout_onchange(void *ctrl, enum element_change_event event, void
|
||||
|
||||
switch (event) {
|
||||
case ON_CHANGE_INIT:
|
||||
ui_auto_shut_down_disable();
|
||||
jljpeg_stream_init();
|
||||
jluvc_set_refresh_cb(ui_uvc_ui_reflush);
|
||||
break;
|
||||
@@ -97,6 +98,7 @@ static int uvc_layout_onchange(void *ctrl, enum element_change_event event, void
|
||||
}
|
||||
dc = (struct draw_context *)arg;
|
||||
/* ui_custom_draw_clear(dc); */
|
||||
/* put_buf(jljpeg_stream_src_data_get(),128); */
|
||||
jlgpu_scheduler_wait_sync();
|
||||
jlgpu_task_clean_up_by_id(dc->gpu_task_head, dc->elm->id, 0x1);
|
||||
jpeg_image_ram(dc, 0, 0, UVC_JPG_WIDTH , UVC_JPG_HEIGHT,
|
||||
@@ -105,6 +107,7 @@ static int uvc_layout_onchange(void *ctrl, enum element_change_event event, void
|
||||
break;
|
||||
case ON_CHANGE_RELEASE:
|
||||
jljpeg_stream_deinit();
|
||||
ui_auto_shut_down_enable();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -1216,6 +1216,10 @@ static void menu_list_anim_ready_cb(struct _ui_anim_t *p)
|
||||
if (elm) {
|
||||
ui_hide(__this->target_page);
|
||||
}
|
||||
if (__this->target_page == ID_WINDOW_NOTICE) {
|
||||
extern u8 create_control_by_menu_set(u8 en);
|
||||
create_control_by_menu_set(1);
|
||||
}
|
||||
UI_SHOW_WINDOW(__this->target_page);
|
||||
}
|
||||
/* 清空过渡动画任务链 */
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include "avilib.h"
|
||||
#include "app_config.h"
|
||||
|
||||
//创建另外的文件存储AVI索引, 节约ram内存。在结束录像时合并索引到AVI文件中
|
||||
#define AVI_INDXE_FILE_ENABLE 1
|
||||
|
||||
//#include <time.h>
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
#define malloc(size) malloc_psram(size)
|
||||
@@ -80,7 +83,7 @@ static size_t avi_write(void *fd, char *buf, size_t len)
|
||||
|
||||
while (r < len) {
|
||||
n = fwrite(buf + r, 1, len - r, (FILE *)fd);
|
||||
if ((ssize_t)n < 0) {
|
||||
if ((ssize_t)n <= 0) {
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -174,53 +177,108 @@ static int avi_add_chunk(avi_t *AVI, unsigned char *tag, unsigned char *data, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int avi_add_idx_chunk(avi_t *AVI, u32 length)
|
||||
{
|
||||
unsigned char c[8] = { 'i', 'd', 'x', '1', 0, 0, 0, 0 };
|
||||
long2str(c + 4, length);
|
||||
|
||||
if (avi_write(AVI->fdes, (char *)c, 8) != 8) {
|
||||
fseek(AVI->fdes, AVI->pos, SEEK_SET);
|
||||
AVI_errno = AVI_ERR_WRITE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update file position */
|
||||
AVI->pos += 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int avi_add_idx_data(avi_t *AVI, unsigned char *data, int length)
|
||||
{
|
||||
/* Output tag, length and data, restore previous position
|
||||
if the write fails */
|
||||
|
||||
length = PAD_EVEN(length);
|
||||
|
||||
if (avi_write(AVI->fdes, (char *)data, length) != length) {
|
||||
fseek(AVI->fdes, AVI->pos, SEEK_SET);
|
||||
AVI_errno = AVI_ERR_WRITE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update file position */
|
||||
|
||||
AVI->pos += length;
|
||||
|
||||
//fprintf(stderr, "pos=%lu %s\n", AVI->pos, tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int avi_add_index_entry(avi_t *AVI, unsigned char *tag, long flags, unsigned long pos, unsigned long len)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (AVI->n_idx >= AVI->max_idx) {
|
||||
if (AVI->index_fdes) {
|
||||
unsigned char c[16];
|
||||
|
||||
size_t old_count = AVI->max_idx; // 原有元素个数
|
||||
size_t elem_size = 16; // 每个元素大小
|
||||
size_t new_count = old_count + 4096; // 扩容后的元素个数
|
||||
size_t new_size = new_count * elem_size; // 扩容后的字节数
|
||||
memcpy(c, tag, 4);
|
||||
long2str(c + 4, flags);
|
||||
//pos - movi_addr
|
||||
long2str(c + 8, pos - (HEADERBYTES - 4));
|
||||
long2str(c + 12, len);
|
||||
|
||||
// 1. 分配新的内存块
|
||||
void *new_idx = malloc(new_size);
|
||||
if (!new_idx) {
|
||||
// 申请失败,保持原状或做错误处理
|
||||
AVI_errno = AVI_ERR_NO_MEM;
|
||||
//写入索引文件
|
||||
if (avi_write(AVI->index_fdes, (char *)c, 16) != 16) {
|
||||
printf("wirte index fail \n");
|
||||
AVI_errno = AVI_ERR_WRITE;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (AVI->n_idx >= AVI->max_idx) {
|
||||
|
||||
memcpy(new_idx, AVI->idx, old_count * elem_size);
|
||||
size_t old_count = AVI->max_idx; // 原有元素个数
|
||||
size_t elem_size = 16; // 每个元素大小
|
||||
size_t new_count = old_count + 4096; // 扩容后的元素个数
|
||||
size_t new_size = new_count * elem_size; // 扩容后的字节数
|
||||
|
||||
free((void *)AVI->idx);
|
||||
// 1. 分配新的内存块
|
||||
void *new_idx = malloc(new_size);
|
||||
if (!new_idx) {
|
||||
// 申请失败,保持原状或做错误处理
|
||||
AVI_errno = AVI_ERR_NO_MEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
AVI->idx = new_idx;
|
||||
AVI->max_idx = new_count;
|
||||
memcpy(new_idx, AVI->idx, old_count * elem_size);
|
||||
|
||||
/* ptr = realloc((void *)AVI->idx, (AVI->max_idx + 4096) * 16); */
|
||||
free((void *)AVI->idx);
|
||||
|
||||
/* if (ptr == 0) { */
|
||||
/* AVI_errno = AVI_ERR_NO_MEM; */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
/* AVI->max_idx += 4096; */
|
||||
/* AVI->idx = (unsigned char((*)[16])) ptr; */
|
||||
AVI->idx = new_idx;
|
||||
AVI->max_idx = new_count;
|
||||
|
||||
/* ptr = realloc((void *)AVI->idx, (AVI->max_idx + 4096) * 16); */
|
||||
|
||||
/* if (ptr == 0) { */
|
||||
/* AVI_errno = AVI_ERR_NO_MEM; */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
/* AVI->max_idx += 4096; */
|
||||
/* AVI->idx = (unsigned char((*)[16])) ptr; */
|
||||
}
|
||||
|
||||
/* Add index entry */
|
||||
|
||||
// fprintf(stderr, "INDEX %s %ld %lu %lu\n", tag, flags, pos, len);
|
||||
|
||||
memcpy(AVI->idx[AVI->n_idx], tag, 4);
|
||||
long2str(AVI->idx[AVI->n_idx] + 4, flags);
|
||||
//TODO
|
||||
//pos - movi_addr
|
||||
long2str(AVI->idx[AVI->n_idx] + 8, pos - (HEADERBYTES - 4));
|
||||
long2str(AVI->idx[AVI->n_idx] + 12, len);
|
||||
}
|
||||
|
||||
/* Add index entry */
|
||||
|
||||
// fprintf(stderr, "INDEX %s %ld %lu %lu\n", tag, flags, pos, len);
|
||||
|
||||
memcpy(AVI->idx[AVI->n_idx], tag, 4);
|
||||
long2str(AVI->idx[AVI->n_idx] + 4, flags);
|
||||
//TODO
|
||||
//pos - movi_addr
|
||||
long2str(AVI->idx[AVI->n_idx] + 8, pos - (HEADERBYTES - 4));
|
||||
long2str(AVI->idx[AVI->n_idx] + 12, len);
|
||||
|
||||
/* Update counter */
|
||||
|
||||
AVI->n_idx++;
|
||||
@@ -288,6 +346,28 @@ avi_t *AVI_open_output_file(char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if AVI_INDXE_FILE_ENABLE
|
||||
//创建索引文件
|
||||
char index_filename[128];
|
||||
char *dir_path = strrchr(filename, '/');
|
||||
strcpy(index_filename, filename);
|
||||
if (dir_path) {
|
||||
dir_path++;
|
||||
sprintf(index_filename + (dir_path - filename), "IDX_****.idx");
|
||||
} else {
|
||||
sprintf(index_filename, "%s.idx", filename);
|
||||
}
|
||||
/* printf("index :%s \n", index_filename); */
|
||||
AVI->index_fdes = fopen(index_filename, "w+");
|
||||
if (AVI->index_fdes == NULL) {
|
||||
printf("fopen index file err \n");
|
||||
fclose(AVI->fdes);
|
||||
AVI_errno = AVI_ERR_OPEN;
|
||||
free(AVI);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write out HEADERBYTES bytes, the header will go here
|
||||
when we are finished with writing */
|
||||
|
||||
@@ -298,6 +378,9 @@ avi_t *AVI_open_output_file(char *filename)
|
||||
if (i != HEADERBYTES) {
|
||||
fclose(AVI->fdes);
|
||||
AVI->fdes = NULL;
|
||||
#if AVI_INDXE_FILE_ENABLE
|
||||
fdelete(AVI->index_fdes);
|
||||
#endif
|
||||
AVI_errno = AVI_ERR_WRITE;
|
||||
free(AVI);
|
||||
return 0;
|
||||
@@ -642,7 +725,7 @@ int avi_update_header(avi_t *AVI)
|
||||
static int avi_close_output_file(avi_t *AVI)
|
||||
{
|
||||
|
||||
int ret, njunk, sampsize, hasIndex, ms_per_frame, frate, idxerror, flag;
|
||||
int ret = 0, njunk, sampsize, hasIndex, ms_per_frame, frate, idxerror, flag;
|
||||
unsigned long movi_len;
|
||||
int hdrl_start, strl_start, j;
|
||||
unsigned char AVI_header[HEADERBYTES];
|
||||
@@ -664,7 +747,43 @@ static int avi_close_output_file(avi_t *AVI)
|
||||
|
||||
idxerror = 0;
|
||||
// fprintf(stderr, "pos=%lu, index_len=%ld \n", AVI->pos, AVI->n_idx*16);
|
||||
ret = avi_add_chunk(AVI, (unsigned char *)"idx1", (unsigned char *)AVI->idx, AVI->n_idx * 16);
|
||||
if (AVI->index_fdes) {
|
||||
//合并索引文件到AVI文件中
|
||||
int buffer_size = 1024;
|
||||
unsigned char *index_data = (unsigned char *)malloc(buffer_size);
|
||||
if (!index_data) {
|
||||
idxerror = 1;
|
||||
AVI_errno = AVI_ERR_NO_MEM;
|
||||
} else {
|
||||
//读取索引文件内容
|
||||
/* fflush(AVI->index_fdes); */
|
||||
u32 index_file_size = flen(AVI->index_fdes);
|
||||
|
||||
fseek(AVI->index_fdes, 0, SEEK_SET);
|
||||
|
||||
size_t read_bytes = avi_read(AVI->index_fdes, (char *)index_data, buffer_size);
|
||||
avi_add_idx_chunk(AVI, index_file_size);
|
||||
while (read_bytes > 0) {
|
||||
//写入AVI文件中
|
||||
ret = avi_add_idx_data(AVI, index_data, read_bytes);
|
||||
hasIndex = (ret == 0);
|
||||
if (ret) {
|
||||
idxerror = 1;
|
||||
AVI_errno = AVI_ERR_WRITE_INDEX;
|
||||
break;
|
||||
}
|
||||
read_bytes = avi_read(AVI->index_fdes, (char *)index_data, buffer_size);
|
||||
}
|
||||
free(index_data);
|
||||
}
|
||||
//删除索引文件
|
||||
fdelete(AVI->index_fdes);
|
||||
//(AVI->index_fdes);
|
||||
AVI->index_fdes = NULL;
|
||||
} else {
|
||||
//内存索引写入AVI文件中
|
||||
ret = avi_add_chunk(AVI, (unsigned char *)"idx1", (unsigned char *)AVI->idx, AVI->n_idx * 16);
|
||||
}
|
||||
hasIndex = (ret == 0);
|
||||
//fprintf(stderr, "pos=%lu, index_len=%d\n", AVI->pos, hasIndex);
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
|
||||
void *fdes; /* File descriptor of AVI file */
|
||||
void *index_fdes; /* File descriptor of AVI file */
|
||||
long mode; /* 0 for reading, 1 for writing */
|
||||
|
||||
long width; /* Width of a video frame */
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#include "media/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "gpio.h"
|
||||
#include "app_task.h"
|
||||
|
||||
#define LOG_TAG_CONST AVI_VIDEO
|
||||
#define LOG_TAG "[AVI_VIDEO]"
|
||||
@@ -122,6 +123,8 @@ static const char *avi_files[] = {
|
||||
"storage/UI_FAT/C/Btest.avi",
|
||||
// 可以继续添加更多文件
|
||||
};
|
||||
static u16 task_switch_flag;
|
||||
|
||||
#define AVI_FILE_COUNT (sizeof(avi_files) / sizeof(avi_files[0]))
|
||||
|
||||
static void parse_list_chunk(FILE *file, long list_end, ChunkCallback callback,
|
||||
@@ -231,7 +234,7 @@ static void pcm_cbuf_deinit(void)
|
||||
log_info("\n[pcm_cbuf_deinit]mem_status:\n");
|
||||
mem_stats();
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
u8 get_avi_audio_status()
|
||||
{
|
||||
if (__this == NULL) {
|
||||
@@ -289,6 +292,13 @@ void avi_play_shutdown(void)
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_info("\n\n avi_play_shutdown rets=%x\n\n", rets);
|
||||
#if TCFG_APP_VIDEO_EN
|
||||
if (app_get_current_mode_name() == APP_MODE_VIDEO) {
|
||||
app_mode_stack_clr(APP_MODE_VIDEO);
|
||||
app_task_switch_back();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (__this == NULL) {
|
||||
return ;
|
||||
}
|
||||
@@ -1941,11 +1951,42 @@ void *get_avi_player_st_handle()
|
||||
{
|
||||
return __this->st;
|
||||
}
|
||||
|
||||
#if TCFG_APP_VIDEO_EN
|
||||
static void app_video_mode_switch(void *priv)
|
||||
{
|
||||
u16 flag = (u16)priv;
|
||||
if (flag != task_switch_flag) {
|
||||
log_info("\n\n %s, %d \n\n", __func__, __LINE__);
|
||||
log_info("flag:%d, %d \n", flag, task_switch_flag);
|
||||
return;
|
||||
}
|
||||
|
||||
++task_switch_flag;
|
||||
if (app_get_current_mode_name() == APP_MODE_VIDEO) {
|
||||
return;
|
||||
}
|
||||
int ret = app_task_switch_to(APP_MODE_VIDEO, NULL_VALUE);
|
||||
if (ret == FALSE) {
|
||||
sys_timeout_add((void *)(long)task_switch_flag, app_video_mode_switch, 500);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *animig_open(char *name, int window_id, int arg)
|
||||
{
|
||||
|
||||
u8 type = 0;
|
||||
|
||||
#if TCFG_APP_VIDEO_EN
|
||||
if (app_get_current_mode_name() != APP_MODE_VIDEO) {
|
||||
int ret = app_task_switch_to(APP_MODE_VIDEO, NULL_VALUE);
|
||||
if (ret == FALSE) {
|
||||
sys_timeout_add((void *)(long)task_switch_flag, app_video_mode_switch, 500);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *f = fopen(name, "r");
|
||||
if (f == NULL) {
|
||||
log_info("open file fail %s", name);
|
||||
|
||||
@@ -60,6 +60,7 @@ struct camera_handle {
|
||||
// JPEG 编码线程
|
||||
char task_name[32];
|
||||
u8 task_runing;
|
||||
u8 task_stoping;
|
||||
OS_SEM task_kill_sem;
|
||||
|
||||
// SPI接收行数统计
|
||||
@@ -164,6 +165,16 @@ static void camera_jpeg_dec_task(void *priv)
|
||||
u32 enc_time;
|
||||
|
||||
while (hdl->task_runing) {
|
||||
if (hdl->task_stoping) {
|
||||
log_char('L');
|
||||
os_time_dly(1);
|
||||
if (lbuf_data) {
|
||||
lbuf_free(lbuf_data);
|
||||
lbuf_data = NULL;
|
||||
}
|
||||
line_cnt = 0;
|
||||
continue;
|
||||
}
|
||||
u8 *chunk = NULL;
|
||||
/* dma_memcpy_wait_idle(); */
|
||||
chunk = queue_buf_pop(__this->qbuf);
|
||||
@@ -222,6 +233,31 @@ static void camera_jpeg_dec_task(void *priv)
|
||||
if (software_jpegenc_line(jpegenc_hdl, cur_bits, remain_size,
|
||||
in_buf, DMA_CAMERA_SIZE, line_cnt, &out_bits_size)) {
|
||||
log_error("software jpgenc line err \n");
|
||||
printf("jpeg enc err,reset !!!\n");
|
||||
//pass当前帧
|
||||
queue_buf_reset(__this->qbuf);
|
||||
line_cnt = 0;
|
||||
if (lbuf_data) {
|
||||
lbuf_free(lbuf_data);
|
||||
lbuf_data = NULL;
|
||||
/* os_time_dly(1); */
|
||||
/* continue; */
|
||||
}
|
||||
//reset jpg_hd
|
||||
software_jpegenc_exit(jpegenc_hdl);
|
||||
jpegenc_hdl = software_jpegenc_init(
|
||||
__this->dev->width,
|
||||
__this->dev->height,
|
||||
__this->dev->width + SPI_FHEAD_SIZE,
|
||||
jpeg_qval);
|
||||
|
||||
if (!jpegenc_hdl) {
|
||||
log_error("software jpegenc init err \n");
|
||||
//下面禁止加打印{
|
||||
os_sem_post(&__this->task_kill_sem);
|
||||
os_time_dly(-1);
|
||||
//}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -308,6 +344,9 @@ int camera_spi_deinit()
|
||||
|
||||
int camera_manager_start(void)
|
||||
{
|
||||
if (!__this) {
|
||||
return -1;
|
||||
}
|
||||
int ret = 0;
|
||||
|
||||
mem_stats();
|
||||
@@ -384,12 +423,12 @@ __err:
|
||||
|
||||
int camera_manager_stop(void)
|
||||
{
|
||||
|
||||
printf("%s %d", __func__, __LINE__);
|
||||
if (!__this) {
|
||||
return -1;
|
||||
}
|
||||
camera_manager_suspend();
|
||||
camera_spi_deinit();
|
||||
|
||||
|
||||
if (__this->task_runing) {
|
||||
__this->task_runing = 0;
|
||||
os_sem_pend(&__this->task_kill_sem, 0);
|
||||
@@ -397,7 +436,6 @@ int camera_manager_stop(void)
|
||||
|
||||
task_kill(__this->task_name);
|
||||
}
|
||||
|
||||
if (__this->qbuf) {
|
||||
queue_buf_destroy(__this->qbuf);
|
||||
__this->qbuf = NULL;
|
||||
@@ -406,14 +444,12 @@ int camera_manager_stop(void)
|
||||
free_psram(__this->lbuf_ptr);
|
||||
__this->lbuf_ptr = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(__this->dma_recv_buf); i++) {
|
||||
if (__this->dma_recv_buf[i]) {
|
||||
free(__this->dma_recv_buf[i]);
|
||||
__this->dma_recv_buf[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -444,7 +480,39 @@ void camera_manager_suspend(void)
|
||||
}
|
||||
__this->dev->supend();
|
||||
}
|
||||
void camera_manager_deep_resume(void)
|
||||
{
|
||||
if (!__this) {
|
||||
return ;
|
||||
}
|
||||
if (!__this->dev) {
|
||||
return ;
|
||||
}
|
||||
queue_buf_reset(__this->qbuf);
|
||||
__this->dma_recv_buf_index = 0;
|
||||
__this->spi_recv_line_cnt = 0;
|
||||
if (__this->dev->init) {
|
||||
__this->dev->init();
|
||||
}
|
||||
camera_spi_init();
|
||||
camera_manager_resume();
|
||||
__this->task_stoping = 0;
|
||||
}
|
||||
|
||||
void camera_manager_deep_suspend(void)
|
||||
{
|
||||
if (!__this) {
|
||||
return ;
|
||||
}
|
||||
if (!__this->dev) {
|
||||
return ;
|
||||
}
|
||||
__this->task_stoping = 1;
|
||||
camera_spi_deinit();
|
||||
if (__this->dev->deinit) {
|
||||
__this->dev->deinit();
|
||||
}
|
||||
}
|
||||
static int camera_manager_dev_check(void)
|
||||
{
|
||||
struct camera_device *dev = NULL;
|
||||
@@ -464,8 +532,8 @@ int camera_manager_init(void)
|
||||
{
|
||||
ASSERT(!__this);
|
||||
__this = malloc(sizeof(struct camera_handle));
|
||||
memset(__this, 0, sizeof(struct camera_handle));
|
||||
camera_manager_dev_check();
|
||||
|
||||
if (!__this->dev) {
|
||||
return -1;
|
||||
}
|
||||
@@ -478,18 +546,22 @@ int camera_manager_init(void)
|
||||
|
||||
int camera_manager_deinit(void)
|
||||
{
|
||||
int ret = -1;
|
||||
if (!__this) {
|
||||
return -1;
|
||||
}
|
||||
if (!__this->dev) {
|
||||
return -1;
|
||||
goto __err;
|
||||
}
|
||||
if (!__this->dev->deinit) {
|
||||
return -1;
|
||||
goto __err;
|
||||
}
|
||||
ret = __this->dev->deinit();
|
||||
__err:
|
||||
if (__this) {
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
}
|
||||
int ret = __this->dev->deinit();
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
return ret;
|
||||
|
||||
}
|
||||
@@ -545,3 +617,4 @@ int camera_manager_get_dev_fps(int *fps)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ int camera_manager_stop(void);
|
||||
void camera_manager_resume(void);
|
||||
void camera_manager_suspend(void);
|
||||
|
||||
void camera_manager_deep_resume(void);
|
||||
void camera_manager_deep_suspend(void);
|
||||
|
||||
int camera_manager_init(void);
|
||||
int camera_manager_deinit(void);
|
||||
|
||||
|
||||
@@ -1,5 +1,363 @@
|
||||
#include "avilib.h"
|
||||
#include "media/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "avi_audio_player.h"
|
||||
//===========================================================================
|
||||
// 使用avilib解码参考
|
||||
//===========================================================================
|
||||
#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 cbuffer_t avi_pcm_cbuf;
|
||||
extern int jljpeg_stream_src_data_copy(u8 *buf, int size);
|
||||
#define VIDEO_DEC_TASK_NAME "VIDEO_DEC"
|
||||
#define PATH_LEN 64
|
||||
#define PCM_CBUF_SIZE (12*1024)
|
||||
|
||||
|
||||
struct video_player {
|
||||
s8(*path)[64];
|
||||
u8 path_number;
|
||||
u8 path_index;
|
||||
u8 play_mode;
|
||||
u8 play_status;
|
||||
int frame_index;
|
||||
int frame_rate;
|
||||
int video_chunks;
|
||||
int audio_chunks;
|
||||
u32 start_msec;
|
||||
u32 pause_msec;
|
||||
u32 curr_msec;
|
||||
u32 audio_offset;
|
||||
u16 tick_id;
|
||||
void *dec_hd;
|
||||
void (*ui_refresh_cb)(int status);
|
||||
u8 *audio_buf;
|
||||
OS_SEM task_kill_sem;
|
||||
} *__player;
|
||||
|
||||
#define __this (__player)
|
||||
|
||||
enum {
|
||||
VIDEO_DEC_MSG_INIT,
|
||||
VIDEO_DEC_MSG_EXIT,
|
||||
VIDEO_DEC_MSG_START,
|
||||
VIDEO_DEC_MSG_STOP,
|
||||
VIDEO_DEC_MSG_UPDATE_FILE,
|
||||
VIDEO_DEC_MSG_TICK,
|
||||
VIDEO_DEC_MSG_SUSPEND,
|
||||
VIDEO_DEC_MSG_RESUME,
|
||||
};
|
||||
enum {
|
||||
VIDEO_DEC_PLAY_MODE_SINGLE,//单次播放
|
||||
VIDEO_DEC_PLAY_MODE_SINGLE_LOOP,//单次循环
|
||||
VIDEO_DEC_PLAY_MODE_LIST,//列表播放,不循环
|
||||
VIDEO_DEC_PLAY_MODE_LIST_LOOP,//列表播放,循环
|
||||
};
|
||||
#if 0//使用video_dec解码时打开
|
||||
u8 get_avi_audio_status()
|
||||
{
|
||||
if (__this == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
static int video_msg_post(int msg, void *priv, int priv_len)
|
||||
{
|
||||
int err = os_taskq_post_type(VIDEO_DEC_TASK_NAME, msg, priv_len, priv);
|
||||
if (err) {
|
||||
printf("%s err::%d\n", __func__, err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int video_dec_player_update_dec_hd()
|
||||
{
|
||||
if (__this->dec_hd) {
|
||||
AVI_close(__this->dec_hd);
|
||||
__this->dec_hd = NULL;
|
||||
}
|
||||
printf("%s path:%s\n", __func__, (char *)__this->path[__this->path_index]);
|
||||
__this->dec_hd = AVI_open_input_file((char *)__this->path[__this->path_index], 1);
|
||||
__this->frame_rate = AVI_frame_rate(__this->dec_hd);
|
||||
__this->audio_chunks = AVI_audio_chunks(__this->dec_hd);
|
||||
__this->video_chunks = AVI_video_frames(__this->dec_hd);
|
||||
__this->frame_index = 0;
|
||||
return 0;
|
||||
}
|
||||
static void video_dec_tick_cb(void *p)
|
||||
{
|
||||
video_msg_post(VIDEO_DEC_MSG_TICK, NULL, 0);
|
||||
}
|
||||
int video_dec_tick_update()
|
||||
{
|
||||
video_msg_post(VIDEO_DEC_MSG_TICK, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
static int video_dec_player_tick()
|
||||
{
|
||||
if (!__this->frame_index) {
|
||||
__this->start_msec = jiffies_msec();
|
||||
}
|
||||
__this->curr_msec = jiffies_msec2offset(__this->start_msec, jiffies_msec());
|
||||
int real_frame_index = __this->curr_msec * __this->frame_rate / 1000;
|
||||
/* printf("%s rf:%d total:%d",__func__,real_frame_index,__this->video_chunks); */
|
||||
if (real_frame_index >= __this->video_chunks) {
|
||||
//stop
|
||||
if (__this->tick_id) {
|
||||
usr_timer_del(__this->tick_id);
|
||||
__this->tick_id = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
AVI_set_video_position(__this->dec_hd, real_frame_index);
|
||||
int keyframe;
|
||||
u32 offset = 0;
|
||||
int frame_len = AVI_frame_size(__this->dec_hd, real_frame_index);
|
||||
u8 *file_buf = malloc(20 * 1024);
|
||||
if (frame_len <= 20 * 1024) {
|
||||
int file_len = AVI_read_frame(__this->dec_hd, (char *)file_buf, &keyframe);
|
||||
//copy_to_ui
|
||||
if (!jljpeg_stream_src_data_copy(file_buf, file_len)) {
|
||||
if (__this->ui_refresh_cb) {
|
||||
__this->ui_refresh_cb(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
int exit = 0;
|
||||
if (__this->video_chunks) {
|
||||
real_frame_index = real_frame_index * __this->audio_chunks / __this->video_chunks;
|
||||
}
|
||||
/* printf("%s %d->%d(%d)",__func__,__this->frame_index,real_frame_index,__this->audio_chunks); */
|
||||
for (int i = __this->frame_index ; i < real_frame_index; i++) {
|
||||
int audio_chunk_size = AVI_audio_size(__this->dec_hd, i);
|
||||
AVI_set_audio_position(__this->dec_hd, __this->audio_offset);
|
||||
int file_len = AVI_read_audio_chunk(__this->dec_hd, (char *)file_buf);
|
||||
//copy_to_pcm_player
|
||||
int len = file_len;
|
||||
u8 *ptr = file_buf;
|
||||
while (len) {
|
||||
int w = cbuf_write(&avi_pcm_cbuf, ptr, len);
|
||||
/* printf("[w] len:%d wl:%d",len,w); */
|
||||
if (w == 0) {
|
||||
/* os_time_dly(1); */
|
||||
exit = 1;
|
||||
break;
|
||||
}
|
||||
ptr += w;
|
||||
len -= w;
|
||||
}
|
||||
if (exit) {
|
||||
__this->frame_index = i;
|
||||
break;
|
||||
}
|
||||
/* printf("[cw] i:%d chunks:%d filelen:%d",i,audio_chunk_size,file_len); */
|
||||
//todo
|
||||
__this->audio_offset += audio_chunk_size;
|
||||
}
|
||||
if (!exit) {
|
||||
__this->frame_index = real_frame_index;
|
||||
}
|
||||
|
||||
if (!__this->frame_index) {
|
||||
__this->frame_index ++;
|
||||
}
|
||||
free(file_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int video_dec_player_start()
|
||||
{
|
||||
int msec = (int)1000 / __this->frame_rate; // /2?
|
||||
if (__this->tick_id) {
|
||||
usr_timer_del(__this->tick_id);
|
||||
}
|
||||
|
||||
__this->tick_id = usr_timer_add(NULL, video_dec_tick_cb, msec, 1);
|
||||
|
||||
|
||||
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, app_audio_volume_max_query(AppVol_MUSIC), NULL); // 音量状态设置
|
||||
audio_dac_set_volume(&dac_hdl, app_audio_volume_max_query(AppVol_MUSIC) / 100); // dac 音量设置
|
||||
|
||||
struct avi_audio_player_param param = {0};
|
||||
param.coding_type = AUDIO_CODING_PCM;
|
||||
param.channel_mode = (AVI_audio_channels(__this->dec_hd) == 1) ? AUDIO_CH_L : AUDIO_CH_MIX;
|
||||
param.sample_rate = AVI_audio_rate(__this->dec_hd);
|
||||
param.bit_rate = AVI_audio_channels(__this->dec_hd) * AVI_audio_rate(__this->dec_hd) * AVI_audio_bits(__this->dec_hd);
|
||||
param.type = AVI_SERVICE_VOICE;
|
||||
printf("simple_rate:%d channel:%d bitrate:%d", param.sample_rate, param.channel_mode, param.bit_rate);
|
||||
// 打开AI voice播放
|
||||
int ret = avi_audio_player_open(NULL, 0, ¶m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int video_dec_player_stop()
|
||||
{
|
||||
|
||||
avi_audio_player_close(0);
|
||||
if (__this->tick_id) {
|
||||
usr_timer_del(__this->tick_id);
|
||||
__this->tick_id = 0;
|
||||
}
|
||||
if (__this->audio_buf) {
|
||||
free(__this->audio_buf);
|
||||
__this->audio_buf = NULL;
|
||||
}
|
||||
if (__this->dec_hd) {
|
||||
AVI_close(__this->dec_hd);
|
||||
__this->dec_hd = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int video_dec_player_suspend()
|
||||
{
|
||||
/* if(__this->tick_id){ */
|
||||
/* usr_timer_del(__this->tick_id); */
|
||||
/* } */
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int video_dec_player_resume()
|
||||
{
|
||||
/* int msec = (int)1000/__this->frame_rate;// /2? */
|
||||
/* if(__this->tick_id){ */
|
||||
/* usr_timer_del(__this->tick_id); */
|
||||
/* } */
|
||||
/* __this->tick_id = usr_timer_add(NULL, video_dec_tick_cb,msec,1); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void video_dec_task(void *p)
|
||||
{
|
||||
int msg[32];
|
||||
int ret;
|
||||
while (1) {
|
||||
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
|
||||
printf("%s msg:%d \n", __func__, msg[0]);
|
||||
if (!__this) {
|
||||
break;
|
||||
}
|
||||
switch (msg[0]) {
|
||||
case VIDEO_DEC_MSG_TICK:
|
||||
video_dec_player_tick();
|
||||
break;
|
||||
case VIDEO_DEC_MSG_UPDATE_FILE:
|
||||
video_dec_player_update_dec_hd();
|
||||
break;
|
||||
case VIDEO_DEC_MSG_START:
|
||||
video_dec_player_start();
|
||||
break;
|
||||
case VIDEO_DEC_MSG_STOP:
|
||||
video_dec_player_stop();
|
||||
break;
|
||||
case VIDEO_DEC_MSG_SUSPEND:
|
||||
video_dec_player_suspend();
|
||||
break;
|
||||
case VIDEO_DEC_MSG_RESUME:
|
||||
video_dec_player_resume();
|
||||
break;
|
||||
case VIDEO_DEC_MSG_EXIT:
|
||||
os_sem_post(&__this->task_kill_sem);
|
||||
os_time_dly(-1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int video_dec_init()
|
||||
{
|
||||
if (!__this) {
|
||||
__this = malloc(sizeof(struct video_player));
|
||||
memset(__this, 0, sizeof(struct video_player));
|
||||
}
|
||||
if (!__this->audio_buf) {
|
||||
__this->audio_buf = malloc(PCM_CBUF_SIZE);
|
||||
}
|
||||
cbuf_init(&avi_pcm_cbuf, __this->audio_buf, PCM_CBUF_SIZE);
|
||||
os_sem_create(&__this->task_kill_sem, 0);
|
||||
//create_task
|
||||
int ret = os_task_create(video_dec_task, NULL, 8, 1024, 1024, VIDEO_DEC_TASK_NAME);
|
||||
if (ret) {
|
||||
printf("%s err\n", __func__);
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int video_dec_deinit()
|
||||
{
|
||||
//kill
|
||||
if (__this->tick_id) {
|
||||
usr_timer_del(__this->tick_id);
|
||||
__this->tick_id = 0;
|
||||
}
|
||||
int ret = video_msg_post(VIDEO_DEC_MSG_EXIT, NULL, 0);
|
||||
|
||||
os_sem_pend(&__this->task_kill_sem, 0);
|
||||
os_sem_del(&__this->task_kill_sem, OS_DEL_ALWAYS);
|
||||
|
||||
task_kill(VIDEO_DEC_TASK_NAME);
|
||||
//free
|
||||
|
||||
if (__this->audio_buf) {
|
||||
free(__this->audio_buf);
|
||||
__this->audio_buf = NULL;
|
||||
}
|
||||
if (__this->dec_hd) {
|
||||
AVI_close(__this->dec_hd);
|
||||
__this->dec_hd = NULL;
|
||||
}
|
||||
if (__this) {
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int video_dec_set_path(s8(*path)[64], u8 path_number)
|
||||
{
|
||||
__this->path = path;
|
||||
__this->path_number = path_number;
|
||||
return 0;
|
||||
}
|
||||
int video_dec_start(u8 index, u8 mode)
|
||||
{
|
||||
if ((index < __this->path_number) && (index >= 0)) {
|
||||
__this->frame_index = index;
|
||||
} else {
|
||||
__this->frame_index = 0;
|
||||
}
|
||||
int ret = 0;
|
||||
ret += video_msg_post(VIDEO_DEC_MSG_UPDATE_FILE, NULL, 0);
|
||||
|
||||
ret += video_msg_post(VIDEO_DEC_MSG_START, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
int video_dec_stop()
|
||||
{
|
||||
int ret = video_msg_post(VIDEO_DEC_MSG_STOP, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
int video_dec_refresh_cb_register(void (*cb)(int status))
|
||||
{
|
||||
if (!__this) {
|
||||
printf("%s not find\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
__this->ui_refresh_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//读取AVI文件视频帧和音频帧行写卡在PC上验证
|
||||
int video_dec_demo(void)
|
||||
{
|
||||
@@ -63,3 +421,5 @@ int video_dec_demo(void)
|
||||
/* os_time_dly(-1); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,11 +31,15 @@ struct video_rec_handle {
|
||||
int video_rate;
|
||||
int sample_rate;
|
||||
void (*ui_refresh_cb)(int status);
|
||||
int bytes_per_sample;
|
||||
};
|
||||
static struct video_rec_handle *video_rec;
|
||||
#define __this (video_rec)
|
||||
|
||||
//摄像头流程 camera_manager_init->start->read->read_done->read...->stop->exit.
|
||||
|
||||
extern uint32_t timer_get_ms(void);
|
||||
|
||||
//摄像头流程 bf30a2_camera_init->start->read->read_done->read...->stop->exit.
|
||||
//麦克风流程 pcm_data_init->read->read_done->read...->exit.
|
||||
|
||||
extern int jljpeg_stream_src_data_copy(u8 *buf, int size);
|
||||
@@ -181,17 +185,17 @@ static void video_show_task(void *priv)
|
||||
frame_cnt = 0;
|
||||
/* break; */
|
||||
} else if (msg[0] == Q_AVI_TASK_REC_STOP) {
|
||||
|
||||
log_debug("avi task rec stop!\n");
|
||||
if (out_fd) {
|
||||
ret = AVI_close(out_fd);
|
||||
if (ret) {
|
||||
log_error("camera devide avi close err :%d \n", ret);
|
||||
ASSERT(0);
|
||||
__this->write_error = 1;
|
||||
/* ASSERT(0); */
|
||||
} else {
|
||||
log_debug("avi write success \n");
|
||||
out_fd = NULL;
|
||||
}
|
||||
out_fd = NULL;
|
||||
}
|
||||
if (__this->pcm_hdl) {
|
||||
pcm_data_exit(__this->pcm_hdl);
|
||||
@@ -229,6 +233,23 @@ static void video_show_task(void *priv)
|
||||
__this->write_error = AVI_write_frame(out_fd, (char *)jpeg_data, jpeg_data_len, 1);
|
||||
}
|
||||
camera_manager_read_done(jpeg_data);
|
||||
#if 0
|
||||
static int cam_last_msec = 0;
|
||||
static int cam_frame_sum = 0;
|
||||
static int cam_frame_cnt = 0;
|
||||
if (cam_last_msec) {
|
||||
u32 cur_msec = jiffies_msec();
|
||||
u32 offset = jiffies_msec2offset(cam_last_msec, cur_msec);
|
||||
cam_frame_sum += offset;
|
||||
cam_frame_cnt ++;
|
||||
if (cam_frame_cnt && cam_frame_sum) {
|
||||
u32 avg = cam_frame_sum / cam_frame_cnt;
|
||||
u32 fps = 1000 / avg;
|
||||
printf("CAM avg:%d fps:%d \n", avg, fps);
|
||||
}
|
||||
}
|
||||
cam_last_msec = jiffies_msec();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (out_fd && (cyc_time != -1)) {
|
||||
@@ -287,14 +308,12 @@ int jlcamera_video_rec_init(void)
|
||||
//初始化驱动
|
||||
ret = camera_manager_init();
|
||||
if (ret) {
|
||||
//TODO
|
||||
return -1;
|
||||
goto __err;
|
||||
}
|
||||
//启动摄像头
|
||||
ret = camera_manager_start();
|
||||
if (ret) {
|
||||
//TODO
|
||||
return -1;
|
||||
goto __err;
|
||||
}
|
||||
int fps;
|
||||
camera_manager_get_dev_fps(&fps);
|
||||
@@ -307,11 +326,19 @@ int jlcamera_video_rec_init(void)
|
||||
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)) {
|
||||
log_error("avi task create fail \n");
|
||||
//TODO
|
||||
return -1;
|
||||
goto __err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__err:
|
||||
log_error("%s err\n", __func__);
|
||||
camera_manager_stop();
|
||||
camera_manager_deinit();
|
||||
if (__this) {
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
@@ -322,22 +349,21 @@ int jlcamera_video_rec_init(void)
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jlcamera_video_rec_deinit(void)
|
||||
{
|
||||
|
||||
printf("%s %d", __func__, __LINE__);
|
||||
/* printf("%s %d", __func__, __LINE__); */
|
||||
/* void dma_memcpy_wait_idle(void); */
|
||||
/* dma_memcpy_wait_idle(); */
|
||||
|
||||
camera_manager_stop();
|
||||
OS_SEM task_kill_sem;
|
||||
os_sem_create(&task_kill_sem, 0);
|
||||
int msg = (int)&task_kill_sem;
|
||||
os_taskq_del_type(__this->avi_task_name, Q_AVI_TASK_REC_START);
|
||||
os_taskq_del_type(__this->avi_task_name, Q_AVI_TASK_REC_STOP);
|
||||
os_taskq_post_type(__this->avi_task_name, Q_AVI_TASK_KILL, 1, &msg);
|
||||
os_sem_pend(&task_kill_sem, 0);
|
||||
os_sem_del(&task_kill_sem, OS_DEL_ALWAYS);
|
||||
task_kill(__this->avi_task_name);
|
||||
|
||||
if (__this) {
|
||||
OS_SEM task_kill_sem;
|
||||
os_sem_create(&task_kill_sem, 0);
|
||||
int msg = (int)&task_kill_sem;
|
||||
os_taskq_del_type(__this->avi_task_name, Q_AVI_TASK_REC_START);
|
||||
os_taskq_del_type(__this->avi_task_name, Q_AVI_TASK_REC_STOP);
|
||||
os_taskq_post_type(__this->avi_task_name, Q_AVI_TASK_KILL, 1, &msg);
|
||||
os_sem_pend(&task_kill_sem, 0);
|
||||
os_sem_del(&task_kill_sem, OS_DEL_ALWAYS);
|
||||
task_kill(__this->avi_task_name);
|
||||
}
|
||||
|
||||
camera_manager_deinit();
|
||||
clock_unlock("camera_video");
|
||||
@@ -442,6 +468,214 @@ static void avi_task(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
//基于音频时间进行补帧(音频包太大有误差)
|
||||
static void avi_task_dup1(void *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
int msg[8];
|
||||
int frame_cnt = 0;
|
||||
int cyc_time = 30; //循环录影时间,单位秒
|
||||
u8 *pcm_data, *jpeg_data;
|
||||
int pcm_data_len, jpeg_data_len;
|
||||
|
||||
char *filename = "storage/sd0/C/VID_****.AVI";
|
||||
avi_t *out_fd = AVI_open_output_file(filename);
|
||||
if (out_fd == NULL) {
|
||||
printf("open file erro\n");
|
||||
os_time_dly(-1);
|
||||
}
|
||||
|
||||
AVI_set_video(out_fd, BF30A2_INPUT_W, BF30A2_INPUT_H, __this->video_rate, "MJPG");
|
||||
AVI_set_audio(out_fd, 1, __this->sample_rate, 16, WAVE_FORMAT_PCM, 0);//默认单声道s16格式
|
||||
|
||||
// --- 用于补帧的统计变量 ---
|
||||
u32 total_audio_bytes = 0; // 累加收到并写入的音频字节数
|
||||
const int bytes_per_sample = __this->bytes_per_sample;
|
||||
const int video_rate = __this->video_rate;
|
||||
const int sample_rate = __this->sample_rate;
|
||||
int dup_frame_cnt = 0; //调试使用
|
||||
|
||||
while (1) {
|
||||
u8 read_data = 0;
|
||||
|
||||
if (os_taskq_accept(ARRAY_SIZE(msg), msg) == OS_TASKQ) {
|
||||
if (msg[0] == Q_AVI_TASK_KILL) {
|
||||
if (out_fd) {
|
||||
AVI_close(out_fd);
|
||||
}
|
||||
printf("avi task exit !\n");
|
||||
os_sem_post((OS_SEM *)msg[1]);
|
||||
os_time_dly(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcm_data_read(__this->pcm_hdl, &pcm_data, &pcm_data_len) == 0) {
|
||||
read_data = 1;
|
||||
AVI_write_audio(out_fd, (char *)pcm_data, pcm_data_len);
|
||||
|
||||
// 累加已写入的音频字节(用于推算应该产生的视频帧数)
|
||||
total_audio_bytes += pcm_data_len;
|
||||
|
||||
pcm_data_read_done(__this->pcm_hdl, pcm_data);
|
||||
}
|
||||
if (bf30a2_camera_data_read(&jpeg_data, &jpeg_data_len) == 0) {
|
||||
read_data = 1;
|
||||
frame_cnt ++;
|
||||
|
||||
AVI_write_frame(out_fd, (char *)jpeg_data, jpeg_data_len, 1);
|
||||
bf30a2_camera_read_done(jpeg_data);
|
||||
|
||||
// 基于音频进度推算并补帧
|
||||
if (total_audio_bytes >= sample_rate * bytes_per_sample) {
|
||||
u32 total_audio_samples = total_audio_bytes / bytes_per_sample; // 整数
|
||||
u32 expected_frames = (total_audio_samples * video_rate) / sample_rate;
|
||||
|
||||
if (expected_frames > frame_cnt) {
|
||||
ret = AVI_dup_frame(out_fd);
|
||||
if (!ret) {
|
||||
dup_frame_cnt++;
|
||||
frame_cnt++;
|
||||
printf("avi dup video frame :%d cur frame:%d \n", dup_frame_cnt, frame_cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (frame_cnt >= __this->video_rate * cyc_time) {
|
||||
ret = AVI_close(out_fd);
|
||||
if (ret) {
|
||||
printf("bf30a2 avi close err :%d \n", ret);
|
||||
|
||||
} else {
|
||||
printf("avi write success \n");
|
||||
}
|
||||
|
||||
out_fd = AVI_open_output_file(filename);
|
||||
if (out_fd == NULL) {
|
||||
printf("open file erro\n");
|
||||
break;
|
||||
}
|
||||
AVI_set_video(out_fd, BF30A2_INPUT_W, BF30A2_INPUT_H, __this->video_rate, "MJPG");
|
||||
AVI_set_audio(out_fd, 1, __this->sample_rate, 16, WAVE_FORMAT_PCM, 0);//默认单声道s16格式
|
||||
frame_cnt = 0;
|
||||
dup_frame_cnt = 0;
|
||||
total_audio_bytes = 0;
|
||||
}
|
||||
|
||||
//没有读到数据
|
||||
if (!read_data) {
|
||||
//根据音频包计算延时
|
||||
u32 delay_ms = ((float)__this->aframe_size / (__this->sample_rate * 2)) * 1000;
|
||||
u32 tick = delay_ms / 10;
|
||||
os_time_dly(tick + 1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//基于系统时间进行补帧
|
||||
static void avi_task_dup2(void *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
int msg[8];
|
||||
int frame_cnt = 0;
|
||||
int cyc_time = 30; //循环录影时间,单位秒
|
||||
u8 *pcm_data, *jpeg_data;
|
||||
int pcm_data_len, jpeg_data_len;
|
||||
|
||||
char *filename = "storage/sd0/C/VID_****.AVI";
|
||||
avi_t *out_fd = AVI_open_output_file(filename);
|
||||
if (out_fd == NULL) {
|
||||
printf("open file erro\n");
|
||||
os_time_dly(-1);
|
||||
}
|
||||
|
||||
AVI_set_video(out_fd, BF30A2_INPUT_W, BF30A2_INPUT_H, __this->video_rate, "MJPG");
|
||||
AVI_set_audio(out_fd, 1, __this->sample_rate, 16, WAVE_FORMAT_PCM, 0);//默认单声道s16格式
|
||||
|
||||
// --- 用于补帧的统计变量 ---
|
||||
const int video_rate = __this->video_rate;
|
||||
u32 start_ms = timer_get_ms(); // 每次 open file 时重置
|
||||
int dup_frame_cnt = 0; // 调试使用
|
||||
|
||||
while (1) {
|
||||
u8 read_data = 0;
|
||||
|
||||
if (os_taskq_accept(ARRAY_SIZE(msg), msg) == OS_TASKQ) {
|
||||
if (msg[0] == Q_AVI_TASK_KILL) {
|
||||
if (out_fd) {
|
||||
AVI_close(out_fd);
|
||||
}
|
||||
printf("avi task exit !\n");
|
||||
os_sem_post((OS_SEM *)msg[1]);
|
||||
os_time_dly(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcm_data_read(__this->pcm_hdl, &pcm_data, &pcm_data_len) == 0) {
|
||||
read_data = 1;
|
||||
AVI_write_audio(out_fd, (char *)pcm_data, pcm_data_len);
|
||||
pcm_data_read_done(__this->pcm_hdl, pcm_data);
|
||||
}
|
||||
if (bf30a2_camera_data_read(&jpeg_data, &jpeg_data_len) == 0) {
|
||||
read_data = 1;
|
||||
frame_cnt ++;
|
||||
AVI_write_frame(out_fd, (char *)jpeg_data, jpeg_data_len, 1);
|
||||
bf30a2_camera_read_done(jpeg_data);
|
||||
|
||||
// --------- 基于系统时钟检查是否需要补帧 ---------
|
||||
u32 now = timer_get_ms();
|
||||
u32 elapsed_ms = now - start_ms;
|
||||
u32 expected_frames = (elapsed_ms * video_rate) / 1000;
|
||||
if (expected_frames > frame_cnt) {
|
||||
ret = AVI_dup_frame(out_fd);
|
||||
if (!ret) {
|
||||
dup_frame_cnt++;
|
||||
frame_cnt++;
|
||||
printf("avi dup video frame :%d cur frame:%d \n", dup_frame_cnt, frame_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (frame_cnt >= __this->video_rate * cyc_time) {
|
||||
ret = AVI_close(out_fd);
|
||||
if (ret) {
|
||||
printf("bf30a2 avi close err :%d \n", ret);
|
||||
|
||||
} else {
|
||||
printf("avi write success \n");
|
||||
}
|
||||
|
||||
out_fd = AVI_open_output_file(filename);
|
||||
if (out_fd == NULL) {
|
||||
printf("open file erro\n");
|
||||
break;
|
||||
}
|
||||
AVI_set_video(out_fd, BF30A2_INPUT_W, BF30A2_INPUT_H, __this->video_rate, "MJPG");
|
||||
AVI_set_audio(out_fd, 1, __this->sample_rate, 16, WAVE_FORMAT_PCM, 0);//默认单声道s16格式
|
||||
frame_cnt = 0;
|
||||
dup_frame_cnt = 0;
|
||||
start_ms = timer_get_ms();
|
||||
}
|
||||
|
||||
//没有读到数据
|
||||
if (!read_data) {
|
||||
//根据音频包计算延时
|
||||
u32 delay_ms = ((float)__this->aframe_size / (__this->sample_rate * 2)) * 1000;
|
||||
u32 tick = delay_ms / 10;
|
||||
os_time_dly(tick + 1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int video_rec_start_demo(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -458,7 +692,8 @@ int video_rec_start_demo(void)
|
||||
}
|
||||
__this->video_rate = BF30A2_INPUT_FPS / 2; //视频帧率
|
||||
|
||||
__this->sample_rate = 8000; //音频采样率
|
||||
__this->sample_rate = 8000; //音频采样率
|
||||
__this->bytes_per_sample = 2; // 单声道 s16 -> 每采样 2 字节
|
||||
__this->aframe_size = 4096;
|
||||
__this->pcm_hdl = pcm_data_init(__this->sample_rate, __this->aframe_size, __this->aframe_size * 10);
|
||||
if (!__this->pcm_hdl) {
|
||||
@@ -473,6 +708,14 @@ int video_rec_start_demo(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* __this->video_rate = 20; //可配置一个摄像头达不到的帧率,模拟需要补帧的情况 */
|
||||
/* //根据系统时间进行补帧 */
|
||||
/* if (os_task_create(avi_task_dup2, __this, 8, 1024, 1024, __this->avi_task_name)) { */
|
||||
/* printf("avi task create fail \n"); */
|
||||
/* //TODO */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user