Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
104
sdk/app/ui/audio_dac_test_ui.c
Normal file
104
sdk/app/ui/audio_dac_test_ui.c
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "audio_media_ctrl/audio_media_ctrl.h"
|
||||
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct audio_dac_test_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_label;
|
||||
lv_obj_t *now_ui;
|
||||
struct msi *audio_play_msi;
|
||||
};
|
||||
|
||||
static void exit_audio_dac_test_ui(lv_event_t * e)
|
||||
{
|
||||
struct audio_dac_test_ui_s *ui_s = (struct audio_dac_test_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_del(ui_s->now_label);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
ui_s->now_label = NULL;
|
||||
|
||||
#if AUDIO_EN
|
||||
if(ui_s->audio_play_msi) {
|
||||
audio_file_play_stop(ui_s->audio_play_msi);
|
||||
ui_s->audio_play_msi = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
|
||||
|
||||
static void enter_audio_dac_test_ui(lv_event_t * e)
|
||||
{
|
||||
struct audio_dac_test_ui_s *ui_s = (struct audio_dac_test_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
// lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
lv_obj_t *label = lv_label_create(lv_scr_act());
|
||||
lv_obj_set_size(label, LV_PCT(100), LV_PCT(100));
|
||||
lv_label_set_text(label, "audio_dac_test");
|
||||
lv_obj_align(label,LV_ALIGN_CENTER,0,0);
|
||||
ui_s->now_label = label;
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
|
||||
#if AUDIO_EN
|
||||
if(ui_s->audio_play_msi) {
|
||||
audio_file_play_stop(ui_s->audio_play_msi);
|
||||
ui_s->audio_play_msi = NULL;
|
||||
}
|
||||
msi_cmd("R_AUDAC", MSI_CMD_AUDAC, MSI_AUDAC_SET_MEDIA_VOLUME, 30);
|
||||
AUDEC_INIT audec_init;
|
||||
audec_init.track_type = MEDIA_TRACK;
|
||||
audec_init.priority = play_interruptible;
|
||||
audec_init.direct_to_dac = 1;
|
||||
audec_init.use_tpc = 0;
|
||||
audec_init.destroy_self = 0;
|
||||
audec_init.src_msi = NULL;
|
||||
ui_s->audio_play_msi = audio_file_play_init("0:count.wav", 1, &audec_init);
|
||||
#endif
|
||||
|
||||
lv_obj_add_event_cb(ui, exit_audio_dac_test_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *audio_dac_test_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct audio_dac_test_ui_s *ui_s = (struct audio_dac_test_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct audio_dac_test_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "audio_dac_test");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_audio_dac_test_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
184
sdk/app/ui/avi_loop_record_ui.c
Normal file
184
sdk/app/ui/avi_loop_record_ui.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/***************************************************************************************
|
||||
这个主要是预览,通过scale3_msi将dvp/csi数据scale到对应的分辨率作为数据流发送出去
|
||||
然后lcd_msi需要接收对应的数据去显示
|
||||
这里只是产生对应数据流,数据用途实际需要终端流(比如lcd流)接收后去处理
|
||||
|
||||
S_PREVIEW_SCALE3 ----> R_VIDEO_P0(320x180)
|
||||
(scale3) (lcd_video_p0)
|
||||
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "avi_encode/avi_encode_msi.h"
|
||||
#include "audio_msi/audio_adc.h"
|
||||
|
||||
struct msi *avi_encode_msi_init(const char *avi_msi_name, uint16_t filter_type, uint8_t rec_time);
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
#define LV_OBJ_AVI_RECORD_FLAG LV_OBJ_FLAG_USER_1
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct avi_encode_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
struct msi *s;
|
||||
struct msi *avi_encode_s;
|
||||
struct msi *jpg_s;
|
||||
|
||||
uint32_t record_time;
|
||||
|
||||
};
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if(val > 0)
|
||||
{
|
||||
if((val&0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch(val>>8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = LV_KEY_PREV;
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = LV_KEY_NEXT;
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
static void start_avi_record_ui(lv_event_t * e)
|
||||
{
|
||||
struct msi *ret = NULL;
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
struct avi_encode_ui_s *ui_s = (struct avi_encode_ui_s *)lv_event_get_user_data(e);
|
||||
if(c == LV_KEY_ENTER)
|
||||
{
|
||||
if(!lv_obj_has_flag(ui_s->now_ui,LV_OBJ_AVI_RECORD_FLAG))
|
||||
{
|
||||
lv_obj_add_flag(ui_s->now_ui, LV_OBJ_AVI_RECORD_FLAG);
|
||||
#if AUDIO_EN
|
||||
auadc_msi_add_output(AUSYS_AUAD, R_AVI_ENCODE_MSI);
|
||||
#endif
|
||||
ret = avi_encode_msi_init(R_AVI_ENCODE_MSI, (uint16_t)~0, 60*1);
|
||||
|
||||
if (!ret) {
|
||||
lv_obj_clear_flag(ui_s->now_ui, LV_OBJ_AVI_RECORD_FLAG);
|
||||
}
|
||||
ui_s->avi_encode_s = ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//已经在录像了
|
||||
os_printf("%s already running\n",__FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void exit_avi_record_ui(lv_event_t * e)
|
||||
{
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'q')
|
||||
{
|
||||
struct avi_encode_ui_s *ui_s = (struct avi_encode_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
#if AUDIO_EN
|
||||
auadc_msi_del_output(AUSYS_AUAD, R_AVI_ENCODE_MSI);
|
||||
#endif
|
||||
msi_del_output(ui_s->jpg_s, NULL, R_AVI_ENCODE_MSI);
|
||||
msi_put(ui_s->jpg_s);
|
||||
msi_destroy(ui_s->avi_encode_s);
|
||||
msi_destroy(ui_s->s);
|
||||
//关闭VIDEO P0的使能,释放占住的scale3的fb
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
set_lvgl_get_key_func(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_avi_encode_ui(lv_event_t * e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct avi_encode_ui_s *ui_s = (struct avi_encode_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
//绑定流到Video_P0显示
|
||||
|
||||
ui_s->s = scale3_msi(S_PREVIEW_SCALE3);
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
|
||||
ui_s->jpg_s = msi_find(AUTO_JPG, 1);
|
||||
if (ui_s->jpg_s)
|
||||
{
|
||||
msi_add_output(ui_s->jpg_s, NULL, R_AVI_ENCODE_MSI);
|
||||
}
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
|
||||
lv_obj_add_event_cb(ui, start_avi_record_ui, LV_EVENT_KEY, ui_s);
|
||||
lv_obj_add_event_cb(ui, exit_avi_record_ui, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *avi_loop_record_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct avi_encode_ui_s *ui_s = (struct avi_encode_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct avi_encode_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "avi_loop_record_ui");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_avi_encode_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
668
sdk/app/ui/avi_playback_ui.c
Normal file
668
sdk/app/ui/avi_playback_ui.c
Normal file
@@ -0,0 +1,668 @@
|
||||
/***************************************************************************************
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "avi_player_msi.h"
|
||||
|
||||
#define CHECK_DIR "AVI"
|
||||
#define EXT_NAME "*avi"
|
||||
#define PLAY_AVI_STREAM_NAME (64)
|
||||
#define ROUTE_PLAYER_MSI_TX_NUM (16)
|
||||
|
||||
enum
|
||||
{
|
||||
PLAY_STATUS_STOP_PLAY = BIT(0),
|
||||
PLAY_STATUS_PLAY_1FPS = BIT(1), //播放一帧,然后自动暂停
|
||||
PLAY_STATUS_PLAY_END = BIT(2), //播放完毕,需要重新播放
|
||||
};
|
||||
|
||||
//转发流的播放流结构体
|
||||
struct player_forward_stream_s
|
||||
{
|
||||
struct os_work work;
|
||||
struct msi *s;
|
||||
struct framebuff *data_s;
|
||||
|
||||
uint32_t magic;
|
||||
uint32_t start_time;
|
||||
uint32_t last_fps_play_time; //上一帧播放的时间(非系统时间,是视频帧的时间)
|
||||
uint8_t play_status; //自己的播放状态,第一bit代表播放或者暂停
|
||||
};
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_style_t g_style;
|
||||
extern lv_indev_t * indev_keypad;
|
||||
|
||||
struct avi_player_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
lv_timer_t *timer;
|
||||
lv_obj_t * label_time;
|
||||
|
||||
struct msi *P0_jpg_msi;
|
||||
struct msi *decode_msi;
|
||||
struct msi *player_msi;
|
||||
struct msi *avi_s;
|
||||
|
||||
uint8_t *play_name;
|
||||
};
|
||||
|
||||
struct avi_list_param
|
||||
{
|
||||
lv_group_t *group;
|
||||
lv_obj_t *ui;
|
||||
struct avi_player_ui_s *ui_s;
|
||||
};
|
||||
|
||||
typedef int (*creat_avi_list_ui)(const char *filename,void *data);
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if(val > 0)
|
||||
{
|
||||
if((val&0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch(val>>8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'a';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'd';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
static void exit_show_filelist(lv_event_t * e)
|
||||
{
|
||||
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_t *list_item = lv_event_get_current_target(e);
|
||||
if(ui_s->now_group)
|
||||
{
|
||||
lv_indev_set_group(indev_keypad, ui_s->now_group);
|
||||
}
|
||||
if(list_item->user_data)
|
||||
{
|
||||
//由于是子控件回调函数需要删除父控件,所以需要用到异步删除,否则删除内部链表会有异常
|
||||
lv_obj_del_async(list_item->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
//进入回放
|
||||
static void enter_playback(lv_event_t * e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_t *list_item = lv_event_get_current_target(e);
|
||||
lv_obj_t *list = list_item->user_data;
|
||||
//将当前的流关闭,内部判断是否=NULL,这里就不判断了
|
||||
|
||||
if(ui_s->avi_s)
|
||||
{
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_destroy(ui_s->avi_s);
|
||||
ui_s->avi_s = NULL;
|
||||
}
|
||||
if(ui_s->play_name)
|
||||
{
|
||||
STREAM_FREE(ui_s->play_name);
|
||||
ui_s->play_name = NULL;
|
||||
}
|
||||
|
||||
os_printf("ui_s->label_time:%X\n",ui_s->label_time);
|
||||
lv_label_set_text(ui_s->label_time, "00:00");
|
||||
|
||||
//重新打开一个视频文件
|
||||
char path[64];
|
||||
const char *filename = lv_list_get_btn_text(list,list_item);
|
||||
os_printf("play filename:%s\n",filename);
|
||||
os_sprintf(path,"0:%s/%s",CHECK_DIR,filename);
|
||||
|
||||
ui_s->play_name = (uint8_t*)STREAM_MALLOC(PLAY_AVI_STREAM_NAME);
|
||||
os_sprintf((char*)ui_s->play_name,"%s_%04d",filename,(uint32_t)os_jiffies());
|
||||
os_printf("struct msi play_name:%s addr:0x%x\n",ui_s->play_name, ui_s->play_name);
|
||||
ui_s->avi_s = avi_player_init((const char *)ui_s->play_name, (const char *)path);
|
||||
if(ui_s->avi_s)
|
||||
{
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
//设置播放一帧,先去停止播放器
|
||||
struct player_forward_stream_s *player_msg = ui_s->player_msi->priv;
|
||||
os_work_cancle2(&player_msg->work, 1);
|
||||
|
||||
msi_add_output(ui_s->avi_s, NULL, S_NEWPLAYER);
|
||||
ui_s->avi_s->enable = 1;
|
||||
|
||||
//重新开始播放,修改启动时间
|
||||
player_msg->last_fps_play_time = 0;
|
||||
player_msg->start_time = os_jiffies();
|
||||
player_msg->magic = os_jiffies() & 0xFF;
|
||||
msi_do_cmd(ui_s->avi_s, MSI_CMD_PLAYER, MSI_PLAYER_MAGIC, player_msg->magic);
|
||||
player_msg->play_status = (PLAY_STATUS_STOP_PLAY|PLAY_STATUS_PLAY_1FPS);
|
||||
|
||||
OS_WORK_REINIT(&player_msg->work);
|
||||
os_run_work_delay(&player_msg->work, 1);
|
||||
|
||||
//文件开始解析
|
||||
}
|
||||
exit_show_filelist(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int avi_list_show(const char *filename,void *data)
|
||||
{
|
||||
struct avi_list_param *param = (struct avi_list_param*)data;
|
||||
lv_obj_t * btn = lv_list_add_btn(param->ui, NULL, (const char *)filename);
|
||||
btn->user_data = (void*)param->ui;
|
||||
if(param->group)
|
||||
{
|
||||
lv_group_add_obj(param->group, btn);
|
||||
}
|
||||
|
||||
//回调函数,进入回放功能
|
||||
lv_obj_add_event_cb(btn, enter_playback, LV_EVENT_CLICKED, param->ui_s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//遍历文件夹
|
||||
static int each_read_file(creat_avi_list_ui fn,void *param)
|
||||
{
|
||||
DIR dir;
|
||||
FILINFO finfo;
|
||||
FRESULT fr;
|
||||
if(!fn)
|
||||
{
|
||||
goto each_read_file_end;
|
||||
}
|
||||
|
||||
fr = f_findfirst(&dir, &finfo, CHECK_DIR, EXT_NAME);
|
||||
|
||||
|
||||
while(fr == FR_OK && finfo.fname[0] != 0)
|
||||
{
|
||||
fn(finfo.fname,param);
|
||||
fr = f_findnext(&dir, &finfo);
|
||||
}
|
||||
|
||||
f_closedir(&dir);
|
||||
each_read_file_end:
|
||||
os_printf("%s:%d\tret:%d\n",__FUNCTION__,__LINE__,fr);
|
||||
return fr;
|
||||
}
|
||||
|
||||
static void clear_list_group_ui(lv_event_t * e)
|
||||
{
|
||||
lv_group_t *group = (lv_group_t *)lv_event_get_user_data(e);
|
||||
os_printf("group:%X\n",group);
|
||||
if(group)
|
||||
{
|
||||
lv_group_del(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void show_filelist(lv_event_t * e)
|
||||
{
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'e')
|
||||
{
|
||||
set_lvgl_get_key_func(NULL);
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
struct avi_list_param param;
|
||||
lv_obj_t *list = lv_list_create(ui_s->now_ui);
|
||||
lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
|
||||
param.ui_s = ui_s;
|
||||
param.ui = list;
|
||||
param.group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, param.group);
|
||||
//创建exit的控件
|
||||
lv_obj_t *list_item = lv_list_add_btn(list, NULL, "exit");
|
||||
list_item->user_data = (void*)list;
|
||||
lv_group_add_obj(param.group, list_item);
|
||||
lv_obj_add_event_cb(list_item, exit_show_filelist, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
|
||||
each_read_file(avi_list_show,(void*)¶m);
|
||||
|
||||
lv_obj_add_event_cb(list, clear_list_group_ui, LV_EVENT_DELETE, param.group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//这里要创建一个流,专门是控制avi播放流的,由jpg解码,发送到这里缓存起来,然后控制播放速度、暂停等
|
||||
//这里使用lvgl的timer来代替workqueue
|
||||
static int32_t player_work(struct os_work *work)
|
||||
{
|
||||
struct player_forward_stream_s *player_msg = (struct player_forward_stream_s *)work;
|
||||
struct framebuff *data_s = NULL;
|
||||
uint32_t time;
|
||||
//static int count = 0;
|
||||
if(!player_msg->s->enable)
|
||||
{
|
||||
goto player_work_get_data;
|
||||
}
|
||||
|
||||
if(!(player_msg->play_status & PLAY_STATUS_STOP_PLAY))
|
||||
{
|
||||
goto player_work_get_data;
|
||||
}
|
||||
|
||||
|
||||
if(player_msg->data_s)
|
||||
{
|
||||
|
||||
time = player_msg->data_s->time;
|
||||
//先检查时间是否合适
|
||||
if(player_msg->start_time + time > os_jiffies())
|
||||
{
|
||||
if(player_msg->magic != player_msg->data_s->datatag)
|
||||
{
|
||||
msi_delete_fb(NULL, player_msg->data_s);
|
||||
player_msg->data_s = NULL;
|
||||
}
|
||||
goto player_work_end;
|
||||
}
|
||||
//再次检查是否符合需要播放(有可能是缓存或者快进导致进入这里)
|
||||
if(player_msg->magic != player_msg->data_s->datatag)
|
||||
{
|
||||
msi_delete_fb(NULL, player_msg->data_s);
|
||||
player_msg->data_s = NULL;
|
||||
_os_printf("=");
|
||||
goto player_work_end;
|
||||
}
|
||||
|
||||
if(player_msg->play_status & PLAY_STATUS_PLAY_1FPS)
|
||||
{
|
||||
player_msg->play_status &= ~(PLAY_STATUS_STOP_PLAY|PLAY_STATUS_PLAY_1FPS);
|
||||
}
|
||||
|
||||
//os_printf("time:%d\tstart_time:%d\tmagic:%d\n",time,player_msg->start_time,player_msg->data_s->datatag);
|
||||
player_msg->last_fps_play_time = time;
|
||||
//判断一下时间是否需要播放
|
||||
data_s = fb_clone(player_msg->data_s, (player_msg->data_s->mtype << 8 | player_msg->data_s->stype), player_msg->s);
|
||||
//准备填好显示、解码参数信息,然后发送到解码的模块去解码,主要如果没有成功要如何处理,这里没有考虑
|
||||
if(data_s)
|
||||
{
|
||||
|
||||
//os_printf("time:%d\ttype:%X\n",time,player_msg->data_s->mtype);
|
||||
|
||||
//如果不是音频,就是视频,就显示
|
||||
if(data_s->mtype != F_AUDIO)
|
||||
{
|
||||
msi_output_fb(player_msg->s, data_s);
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果是音频,看看是否需要暂停的,如果是,则不播放,因为可能是快进快退,这个时候是不需要去播音频
|
||||
if(!(player_msg->play_status & PLAY_STATUS_STOP_PLAY))
|
||||
{
|
||||
msi_delete_fb(player_msg->s, data_s);
|
||||
}
|
||||
else
|
||||
{
|
||||
msi_output_fb(player_msg->s, data_s);
|
||||
}
|
||||
}
|
||||
|
||||
msi_delete_fb(player_msg->s, player_msg->data_s);
|
||||
player_msg->data_s = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
player_work_get_data:
|
||||
if(!player_msg->data_s)
|
||||
{
|
||||
player_msg->data_s = msi_get_fb(player_msg->s, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(player_msg->magic != player_msg->data_s->datatag)
|
||||
{
|
||||
msi_delete_fb(NULL, player_msg->data_s);
|
||||
player_msg->data_s = NULL;
|
||||
goto player_work_end;
|
||||
}
|
||||
}
|
||||
|
||||
player_work_end:
|
||||
os_run_work_delay(work, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int32_t route_player_action(struct msi *msi, uint32_t cmd_id, uint32_t param1, uint32_t param2)
|
||||
{
|
||||
int32_t ret = RET_OK;
|
||||
struct player_forward_stream_s *msg = (struct player_forward_stream_s *)msi->priv;
|
||||
switch (cmd_id)
|
||||
{
|
||||
// 帮忙转发,但是永远不需要放在队列中
|
||||
case MSI_CMD_TRANS_FB:
|
||||
{
|
||||
struct framebuff *data = (struct framebuff *)param1;
|
||||
//过滤一下没有用的数据包,只是接收play_time_start之后的数据包
|
||||
//os_printf("msg->magic:%d data->datatag:%d\n",msg->magic,data->datatag);
|
||||
if(!(msg->magic == data->datatag))
|
||||
{
|
||||
ret = RET_OK + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_PRE_DESTROY:
|
||||
{
|
||||
if (msg) {
|
||||
|
||||
os_work_cancle2(&msg->work, 1);
|
||||
|
||||
if(msg->data_s)
|
||||
{
|
||||
os_printf("msg->data_s:%X\n",msg->data_s);
|
||||
msi_delete_fb(NULL, msg->data_s);
|
||||
msg->data_s = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
if(msg)
|
||||
{
|
||||
STREAM_FREE(msg);
|
||||
|
||||
msi->priv = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
//struct framebuff *fb = (struct framebuff *)param1;
|
||||
//os_printf("ui free fb:0x%x\n",fb);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//创建播放器的流,这个流主要实现的是控制速度转发作用,暂时控制的是视频
|
||||
//如果要控制音频,需要计算时间来控制速度
|
||||
static struct msi *route_player_msi(const char *name)
|
||||
{
|
||||
struct msi *msi = msi_new(name, 16, NULL);
|
||||
|
||||
if (!msi) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct player_forward_stream_s *msg = (struct player_forward_stream_s*)msi->priv;
|
||||
|
||||
if (!msg) {
|
||||
msg = (struct player_forward_stream_s *)STREAM_ZALLOC(sizeof(struct player_forward_stream_s));
|
||||
msg->s = msi;
|
||||
msi->priv = msg;
|
||||
msg->start_time = os_jiffies();
|
||||
msg->data_s = NULL;
|
||||
msg->magic = 0;
|
||||
msg->play_status = (PLAY_STATUS_STOP_PLAY|PLAY_STATUS_PLAY_1FPS);
|
||||
msg->last_fps_play_time = 0;
|
||||
|
||||
//fbpool_init(&msg->tx_pool, ROUTE_PLAYER_MSI_TX_NUM);
|
||||
msi->action = route_player_action;
|
||||
msi->enable = 1;
|
||||
|
||||
OS_WORK_INIT(&msg->work, player_work, 0);
|
||||
os_run_work_delay(&msg->work, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
msi_destroy(msi);
|
||||
msi = NULL;
|
||||
}
|
||||
|
||||
return msi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void player_locate_ctrl_ui(lv_event_t * e)
|
||||
{
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
struct player_forward_stream_s *player_msg = ui_s->player_msi->priv;
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
//printf("c:%d\n",c);
|
||||
switch(c)
|
||||
{
|
||||
//后退
|
||||
case 'a':
|
||||
{
|
||||
os_work_cancle2(&player_msg->work, 1);
|
||||
uint32_t now_play_time = msi_do_cmd(ui_s->avi_s, MSI_CMD_PLAYER, MSI_REWIND_INDEX, player_msg->last_fps_play_time);
|
||||
//重新开始播放,修改启动时间
|
||||
player_msg->last_fps_play_time = now_play_time;
|
||||
player_msg->start_time = os_jiffies() - now_play_time;
|
||||
player_msg->magic = os_jiffies() & 0xFF;
|
||||
msi_do_cmd(ui_s->avi_s, MSI_CMD_PLAYER, MSI_PLAYER_MAGIC, player_msg->magic);
|
||||
player_msg->play_status = (PLAY_STATUS_STOP_PLAY|PLAY_STATUS_PLAY_1FPS);
|
||||
|
||||
OS_WORK_REINIT(&player_msg->work);
|
||||
os_run_work_delay(&player_msg->work, 1);
|
||||
}
|
||||
|
||||
break;
|
||||
//前进
|
||||
case 'd':
|
||||
{
|
||||
os_work_cancle2(&player_msg->work, 1);
|
||||
uint32_t now_play_time = msi_do_cmd(ui_s->avi_s, MSI_CMD_PLAYER, MSI_FORWARD_INDEX, player_msg->last_fps_play_time);
|
||||
//重新开始播放,修改启动时间
|
||||
player_msg->last_fps_play_time = now_play_time;
|
||||
player_msg->start_time = os_jiffies() - now_play_time;
|
||||
player_msg->magic = os_jiffies() & 0xFF;
|
||||
msi_do_cmd(ui_s->avi_s, MSI_CMD_PLAYER, MSI_PLAYER_MAGIC, player_msg->magic);
|
||||
player_msg->play_status = (PLAY_STATUS_STOP_PLAY|PLAY_STATUS_PLAY_1FPS);
|
||||
OS_WORK_REINIT(&player_msg->work);
|
||||
os_run_work_delay(&player_msg->work, 1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void player_ctrl_ui(lv_event_t * e)
|
||||
{
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
struct player_forward_stream_s *player_msg = ui_s->player_msi->priv;
|
||||
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
||||
//根据播放状态设置
|
||||
if(player_msg->play_status&PLAY_STATUS_STOP_PLAY)
|
||||
{
|
||||
player_msg->play_status &= (~PLAY_STATUS_STOP_PLAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
//重新开始播放,修改启动时间
|
||||
player_msg->start_time = os_jiffies() - player_msg->last_fps_play_time;
|
||||
player_msg->play_status |= PLAY_STATUS_STOP_PLAY;
|
||||
os_printf("################## stop time:%d\tlast_time:%d\n",player_msg->start_time,player_msg->last_fps_play_time);
|
||||
}
|
||||
}
|
||||
static void exit_player_ui(lv_event_t * e)
|
||||
{
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'q')
|
||||
{
|
||||
lv_timer_del(ui_s->timer);
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_destroy(ui_s->P0_jpg_msi);
|
||||
msi_destroy(ui_s->decode_msi);
|
||||
msi_destroy(ui_s->player_msi);
|
||||
msi_destroy(ui_s->avi_s);
|
||||
|
||||
ui_s->avi_s = NULL;
|
||||
ui_s->player_msi = NULL;
|
||||
ui_s->decode_msi = NULL;
|
||||
ui_s->P0_jpg_msi = NULL;
|
||||
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
if(ui_s->play_name)
|
||||
{
|
||||
STREAM_FREE(ui_s->play_name);
|
||||
ui_s->play_name = NULL;
|
||||
}
|
||||
set_lvgl_get_key_func(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void player_ui_timer(lv_timer_t *t)
|
||||
{
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)t->user_data;
|
||||
if(ui_s->avi_s)
|
||||
{
|
||||
//获取当前播放器的流结构体
|
||||
struct player_forward_stream_s *player_msg = ui_s->player_msi->priv;
|
||||
//os_printf("play time:%d\tstart_time:%d\n",player_msg->last_fps_play_time,player_msg->start_time);
|
||||
char show_time[64];
|
||||
sprintf(show_time,"%02d:%02d",(player_msg->last_fps_play_time/1000)/60,(player_msg->last_fps_play_time/1000)%60);
|
||||
lv_label_set_text(ui_s->label_time, show_time);
|
||||
|
||||
//判断文件已经播放完毕,如果需要重新播放,则重新建立播放文件
|
||||
int status = msi_do_cmd(ui_s->avi_s, MSI_CMD_PLAYER, MSI_PLAYER_STATUS, 0);
|
||||
if(status)
|
||||
{
|
||||
os_printf("status:%d\n",status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void enter_player_ui(lv_event_t * e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_t *base_ui = ui_s->base_ui;
|
||||
lv_obj_add_flag(base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
//播放转发发送到P0,控制速度
|
||||
ui_s->player_msi = route_player_msi(S_NEWPLAYER);
|
||||
if (ui_s->player_msi) {
|
||||
msi_add_output(ui_s->player_msi, NULL, "R_AUDAC");
|
||||
msi_add_output(ui_s->player_msi, NULL, SR_OTHER_JPG);
|
||||
ui_s->player_msi->enable = 1;
|
||||
}
|
||||
|
||||
//SR_OTHER_JPG接收数据,然后发送到decode
|
||||
ui_s->P0_jpg_msi = jpg_decode_msg_msi(SR_OTHER_JPG,640,360,640,360,FSTYPE_YUV_P0);
|
||||
if (ui_s->P0_jpg_msi) {
|
||||
msi_add_output(ui_s->P0_jpg_msi, NULL, S_JPG_DECODE);
|
||||
ui_s->P0_jpg_msi->enable = 1;
|
||||
}
|
||||
|
||||
//decode发送到S_NEWPLAYER控制速度后,转发到P0
|
||||
ui_s->decode_msi = jpg_decode_msi(S_JPG_DECODE);
|
||||
if (ui_s->decode_msi) {
|
||||
msi_add_output(ui_s->decode_msi, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->decode_msi->enable = 1;
|
||||
}
|
||||
|
||||
//创建lvgl的timer,用于获取播放的时间
|
||||
|
||||
ui_s->label_time = lv_label_create(ui);
|
||||
lv_label_set_text(ui_s->label_time, "00:00");
|
||||
lv_obj_align(ui_s->label_time,LV_ALIGN_TOP_MID,0,0);
|
||||
ui_s->timer = lv_timer_create(player_ui_timer, 100, (void*)ui_s);
|
||||
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_player_ui, LV_EVENT_KEY, ui_s);
|
||||
//控制暂停、播放
|
||||
lv_obj_add_event_cb(ui, player_ctrl_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
|
||||
//快进快退,一次尝试快进5秒,一次尝试快退5秒
|
||||
lv_obj_add_event_cb(ui, player_locate_ctrl_ui, LV_EVENT_KEY, ui_s);
|
||||
|
||||
//弹出菜单栏,用于切换分辨率
|
||||
lv_obj_add_event_cb(ui, show_filelist, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *avi_playback_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct avi_player_ui_s *ui_s = (struct avi_player_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct avi_player_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
ui_s->play_name = NULL;
|
||||
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "avi_playback_ui");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_player_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
174
sdk/app/ui/avi_record_ui.c
Normal file
174
sdk/app/ui/avi_record_ui.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/***************************************************************************************
|
||||
这个主要是预览,通过scale3_msi将dvp/csi数据scale到对应的分辨率作为数据流发送出去
|
||||
然后lcd_msi需要接收对应的数据去显示
|
||||
这里只是产生对应数据流,数据用途实际需要终端流(比如lcd流)接收后去处理
|
||||
|
||||
S_PREVIEW_SCALE3 ----> R_VIDEO_P0(320x180)
|
||||
(scale3) (lcd_video_p0)
|
||||
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "record/avi_record_msi.h"
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
#define LV_OBJ_AVI_RECORD_FLAG LV_OBJ_FLAG_USER_1
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct avi_record_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
struct msi *s;
|
||||
|
||||
uint32_t record_time;
|
||||
|
||||
};
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if(val > 0)
|
||||
{
|
||||
if((val&0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch(val>>8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = LV_KEY_PREV;
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = LV_KEY_NEXT;
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
static void avi_record_end_callback(void *user_priv)
|
||||
{
|
||||
struct avi_record_ui_s *ui_s = (struct avi_record_ui_s *)user_priv;
|
||||
|
||||
lv_obj_clear_flag(ui_s->now_ui, LV_OBJ_AVI_RECORD_FLAG);
|
||||
}
|
||||
|
||||
static void start_avi_record_ui(lv_event_t * e)
|
||||
{
|
||||
uint32_t *ret = NULL;
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
struct avi_record_ui_s *ui_s = (struct avi_record_ui_s *)lv_event_get_user_data(e);
|
||||
if(c == LV_KEY_ENTER)
|
||||
{
|
||||
if(!lv_obj_has_flag(ui_s->now_ui,LV_OBJ_AVI_RECORD_FLAG))
|
||||
{
|
||||
lv_obj_add_flag(ui_s->now_ui, LV_OBJ_AVI_RECORD_FLAG);
|
||||
#if AUDIO_EN
|
||||
ret = avi_record_msi_init(1280, 720, 30, 8000, 60*1, avi_record_end_callback, ui_s);
|
||||
#else
|
||||
ret = avi_record_msi_init(1280, 720, 30, 0, 60*1, avi_record_end_callback, ui_s);
|
||||
#endif
|
||||
if (!ret) {
|
||||
lv_obj_clear_flag(ui_s->now_ui, LV_OBJ_AVI_RECORD_FLAG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//已经在录像了
|
||||
os_printf("%s already running\n",__FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void exit_avi_record_ui(lv_event_t * e)
|
||||
{
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'q')
|
||||
{
|
||||
struct avi_record_ui_s *ui_s = (struct avi_record_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
avi_record_msi_deinit();
|
||||
msi_destroy(ui_s->s);
|
||||
//关闭VIDEO P0的使能,释放占住的scale3的fb
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
set_lvgl_get_key_func(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_avi_record_ui(lv_event_t * e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct avi_record_ui_s *ui_s = (struct avi_record_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
//绑定流到Video_P0显示
|
||||
|
||||
ui_s->s = scale3_msi(S_PREVIEW_SCALE3);
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
|
||||
lv_obj_add_event_cb(ui, start_avi_record_ui, LV_EVENT_KEY, ui_s);
|
||||
lv_obj_add_event_cb(ui, exit_avi_record_ui, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *avi_record_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct avi_record_ui_s *ui_s = (struct avi_record_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct avi_record_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "avi_record_ui");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_avi_record_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
41
sdk/app/ui/llm_jpg_decode_ui.c
Normal file
41
sdk/app/ui/llm_jpg_decode_ui.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
|
||||
extern lv_style_t g_style;
|
||||
|
||||
lv_obj_t *main_LLM_vision_ui(lv_obj_t *base_ui, lv_group_t *group)
|
||||
{
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
//static const uint16_t filter[] = { FSTYPE_JPG_FILE, FSTYPE_JPG_CAMERA0, FSTYPE_NONE };
|
||||
|
||||
struct msi *decode_s = jpg_decode_msi(S_JPG_DECODE);
|
||||
//将解码的数据推送到Video P0和Video P1显示
|
||||
if (decode_s)
|
||||
{
|
||||
msi_add_output(decode_s, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("jpg decode new msi failed\n");
|
||||
}
|
||||
|
||||
struct msi *jpg_decode_msg_s = jpg_decode_msg_msi(S_NET_JPEG, 320, 320, 320, 320, FSTYPE_JPG_FILE);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (jpg_decode_msg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(jpg_decode_msg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_FORCE_TYPE, FSTYPE_YUV_P0);
|
||||
msi_do_cmd(jpg_decode_msg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 0 << 16 | 0);
|
||||
msi_add_output(jpg_decode_msg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("jpg decode msg 0 new msi failed\n");
|
||||
}
|
||||
|
||||
return base_ui;
|
||||
}
|
||||
34
sdk/app/ui/lvgl_ui.h
Normal file
34
sdk/app/ui/lvgl_ui.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef __LVGL_UI_H
|
||||
#define __LVGL_UI_H
|
||||
#include "lvgl/lvgl.h"
|
||||
lv_obj_t *preview_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h);
|
||||
lv_obj_t *preview_usb_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *photo_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *preview_sim_video_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *preview_dvp_csi_usb_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *preview_qc_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *audio_dac_test_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *touch_pad_test_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *preview_encode_takephoto_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *avi_record_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *avi_loop_record_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *avi_playback_ui(lv_group_t *group, lv_obj_t *base_ui);
|
||||
lv_obj_t *mp4_player_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h);
|
||||
lv_obj_t *mp4_record_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h);
|
||||
lv_obj_t *takephoto_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h);
|
||||
lv_obj_t *main_LLM_vision_ui(lv_obj_t *base_ui, lv_group_t *group);
|
||||
#include "basic_include.h"
|
||||
#include "lib/multimedia/msi.h"
|
||||
#include "scale_msi.h"
|
||||
#include "jpg_concat_msi.h"
|
||||
#include "scale3_normal_msi.h"
|
||||
extern struct msi *jpg_decode_msg_msi(const char *name, uint16_t out_w, uint16_t out_h, uint16_t step_w, uint16_t step_h, uint32_t filter);
|
||||
extern struct msi *sim_video_more_msi(const char *name, uint16_t w, uint16_t h, uint16_t *sim_filter);
|
||||
extern struct msi *jpg_decode_msi(const char *name);
|
||||
extern struct msi *route_msi(const char *name);
|
||||
extern struct msi *sim_video_msi(const char *name, uint16_t w, uint16_t h, uint8_t top);
|
||||
extern struct msi *gen420_msi_init(uint16_t w, uint16_t h, uint16_t *filter_type);
|
||||
extern struct msi *jpg_thumb_msi_init(const char *msi_name, uint16_t filter);
|
||||
|
||||
void set_lvgl_get_key_func(void *func);
|
||||
#endif
|
||||
116
sdk/app/ui/main_ui.c
Normal file
116
sdk/app/ui/main_ui.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "project_config.h"
|
||||
#include "lvgl_ui.h"
|
||||
|
||||
enum UI_MODE
|
||||
{
|
||||
MINI_DV_UI,
|
||||
IPC_UI,
|
||||
BBM_UI,
|
||||
CHILDREN_UI,
|
||||
POCKET_CAMERA_UI, //拇指相机ui的demo
|
||||
LLM_VISION_UI,
|
||||
};
|
||||
|
||||
#ifndef DEFINE_UI
|
||||
#define DEFINE_UI POCKET_CAMERA_UI
|
||||
#endif
|
||||
|
||||
lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
|
||||
|
||||
lv_obj_t *main_Mini_DV_ui(lv_obj_t *base_ui,lv_group_t *group)
|
||||
{
|
||||
lv_obj_t *btn;
|
||||
//可以打印系统一些信息
|
||||
// btn = system_msg_ui(group,base_ui);
|
||||
//预览dvp的镜头数据
|
||||
btn = preview_ui(group,base_ui,320,240);
|
||||
btn = preview_usb_ui(group,base_ui);
|
||||
btn = photo_ui(group,base_ui);
|
||||
btn = preview_sim_video_ui(group,base_ui);
|
||||
btn = preview_dvp_csi_usb_ui(group,base_ui);
|
||||
btn = preview_qc_ui(group,base_ui);
|
||||
btn = audio_dac_test_ui(group,base_ui);
|
||||
btn = touch_pad_test_ui(group,base_ui);
|
||||
btn = preview_encode_takephoto_ui(group,base_ui);
|
||||
btn = avi_record_ui(group,base_ui);
|
||||
btn = avi_loop_record_ui(group,base_ui);
|
||||
btn = avi_playback_ui(group,base_ui);
|
||||
btn = mp4_player_ui(group,base_ui,320,240);
|
||||
btn = mp4_record_ui(group,base_ui,320,240);
|
||||
|
||||
|
||||
//可以进行录像拍照
|
||||
// btn = preview_encode_selct_ui(group,base_ui);
|
||||
//播放自己录制的视频文件
|
||||
// btn = player2_ui(group,base_ui);
|
||||
return base_ui;
|
||||
}
|
||||
|
||||
lv_obj_t *main_pocket_camera_ui(lv_obj_t *base_ui,lv_group_t *group)
|
||||
{
|
||||
// lv_obj_t *btn;
|
||||
// //可以打印系统一些信息
|
||||
// // btn = system_msg_ui(group,base_ui);
|
||||
// //预览dvp的镜头数据
|
||||
// btn = preview_ui(group,base_ui,160,128);
|
||||
// btn = takephoto_ui(group,base_ui,160,128);
|
||||
// btn = mp4_player_ui(group,base_ui,160,128);
|
||||
// btn = mp4_record_ui(group,base_ui,160,128);
|
||||
// return base_ui;
|
||||
// 白色大字 "Hello TXW82x!" 居中显示
|
||||
lv_obj_t *label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Hello TXW82x!");
|
||||
lv_obj_set_style_text_color(label, lv_color_white(), 0);
|
||||
lv_obj_set_style_text_font(label, &lv_font_montserrat_24, 0);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
|
||||
|
||||
// 红色按钮
|
||||
lv_obj_t *btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_set_style_bg_color(btn, lv_color_make(0xFF, 0x00, 0x00), 0);
|
||||
lv_obj_set_size(btn, 100, 50);
|
||||
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 30);
|
||||
lv_obj_t *btn_text = lv_label_create(btn);
|
||||
lv_label_set_text(btn_text, "TEST");
|
||||
lv_group_add_obj(group, btn);
|
||||
return base_ui;
|
||||
}
|
||||
|
||||
extern void common_takephoto_normal_init(const char *thumb_msi_name);
|
||||
extern void common_takephoto_over_dpi_init(uint8_t jpg_num);
|
||||
extern struct msi *scale3_normal_msi2(const char *name, uint8_t force_stype, uint16_t ow, uint16_t oh);
|
||||
lv_obj_t *main_ui(lv_obj_t *base_ui)
|
||||
{
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
lv_obj_t * ui = lv_list_create(lv_scr_act());
|
||||
// lv_obj_add_style(ui,&g_style,0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
switch(DEFINE_UI)
|
||||
{
|
||||
case MINI_DV_UI:
|
||||
main_Mini_DV_ui(ui,group);
|
||||
break;
|
||||
case IPC_UI:
|
||||
break;
|
||||
case BBM_UI:
|
||||
lv_obj_add_style(ui,&g_style,0);
|
||||
break;
|
||||
case CHILDREN_UI:
|
||||
break;
|
||||
case POCKET_CAMERA_UI:
|
||||
//支持大分辨拍照或者缩略图
|
||||
scale3_normal_msi2(S_PREVIEW_SCALE3, FSTYPE_YUV_P0, 168, 128);
|
||||
common_takephoto_normal_init(R_THUMB);
|
||||
common_takephoto_over_dpi_init(JPGID0);
|
||||
main_pocket_camera_ui(ui,group);
|
||||
break;
|
||||
case LLM_VISION_UI:
|
||||
main_LLM_vision_ui(ui,group);
|
||||
break;
|
||||
}
|
||||
return ui;
|
||||
}
|
||||
5
sdk/app/ui/main_ui.h
Normal file
5
sdk/app/ui/main_ui.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifndef __MAIN_UI_H
|
||||
#define __MAIN_UI_H
|
||||
#include "lvgl/lvgl.h"
|
||||
lv_obj_t *main_ui(lv_obj_t *base_ui);
|
||||
#endif
|
||||
439
sdk/app/ui/mp4_player_ui.c
Normal file
439
sdk/app/ui/mp4_player_ui.c
Normal file
@@ -0,0 +1,439 @@
|
||||
/***************************************************************************************
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "avi_player_msi.h"
|
||||
#include "audio_media_ctrl/audio_code_ctrl.h"
|
||||
#include "fs/fatfs/osal_file.h"
|
||||
|
||||
struct msi *h264_decode_msg_msi(const char *name, uint16_t out_w, uint16_t out_h, uint16_t step_w, uint16_t step_h, uint32_t filter);
|
||||
struct msi *h264_decode_msi(const char *name, uint8_t only_I_H264);
|
||||
struct msi *mp4_demux_msi_init(const char *msi_name, const char *filename);
|
||||
void h264_drv_init();
|
||||
|
||||
#define CHECK_DIR "MP4"
|
||||
#define EXT_NAME "*mp4"
|
||||
#define PLAY_AVI_STREAM_NAME (64)
|
||||
#define ROUTE_PLAYER_MSI_TX_NUM (16)
|
||||
|
||||
enum
|
||||
{
|
||||
PLAY_STATUS_STOP_PLAY = BIT(0),
|
||||
PLAY_STATUS_PLAY_1FPS = BIT(1), // 播放一帧,然后自动暂停
|
||||
PLAY_STATUS_PLAY_END = BIT(2), // 播放完毕,需要重新播放
|
||||
};
|
||||
|
||||
// 转发流的播放流结构体
|
||||
struct player_forward_stream_s
|
||||
{
|
||||
struct os_work work;
|
||||
struct msi *s;
|
||||
struct framebuff *data_s;
|
||||
|
||||
uint32_t magic;
|
||||
uint32_t start_time;
|
||||
uint32_t last_fps_play_time; // 上一帧播放的时间(非系统时间,是视频帧的时间)
|
||||
uint8_t play_status; // 自己的播放状态,第一bit代表播放或者暂停
|
||||
};
|
||||
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_style_t g_style;
|
||||
extern lv_indev_t *indev_keypad;
|
||||
|
||||
struct mp4_player_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
uint16_t w, h;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
lv_timer_t *timer;
|
||||
lv_obj_t *label_time;
|
||||
|
||||
struct msi *P0_jpg_msi;
|
||||
struct msi *decode_msi;
|
||||
struct msi *mp4_s;
|
||||
struct msi *aac_msi;
|
||||
|
||||
uint8_t *play_name;
|
||||
uint8_t start : 1, rev : 7;
|
||||
};
|
||||
|
||||
struct avi_list_param
|
||||
{
|
||||
lv_group_t *group;
|
||||
lv_obj_t *ui;
|
||||
struct mp4_player_ui_s *ui_s;
|
||||
};
|
||||
|
||||
typedef int (*creat_avi_list_ui)(const char *filename, void *data);
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if (val > 0)
|
||||
{
|
||||
if ((val & 0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch (val >> 8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'a';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'd';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
static void exit_show_filelist(lv_event_t *e)
|
||||
{
|
||||
os_printf("%s:%d\n", __FUNCTION__, __LINE__);
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
lv_obj_t *list_item = lv_event_get_current_target(e);
|
||||
if (ui_s->now_group)
|
||||
{
|
||||
lv_indev_set_group(indev_keypad, ui_s->now_group);
|
||||
}
|
||||
if (list_item->user_data)
|
||||
{
|
||||
// 由于是子控件回调函数需要删除父控件,所以需要用到异步删除,否则删除内部链表会有异常
|
||||
lv_obj_del_async(list_item->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
// 进入回放
|
||||
static void enter_playback(lv_event_t *e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
lv_obj_t *list_item = lv_event_get_current_target(e);
|
||||
lv_obj_t *list = list_item->user_data;
|
||||
// 将当前的流关闭,内部判断是否=NULL,这里就不判断了
|
||||
|
||||
if (ui_s->mp4_s)
|
||||
{
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_destroy(ui_s->mp4_s);
|
||||
ui_s->mp4_s = NULL;
|
||||
}
|
||||
|
||||
#if AUDIO_EN
|
||||
if (ui_s->aac_msi)
|
||||
{
|
||||
// msi_destroy(ui_s->aac_msi);
|
||||
audio_decode_deinit(ui_s->aac_msi);
|
||||
ui_s->aac_msi = NULL;
|
||||
}
|
||||
#endif
|
||||
if (ui_s->play_name)
|
||||
{
|
||||
STREAM_FREE(ui_s->play_name);
|
||||
ui_s->play_name = NULL;
|
||||
}
|
||||
|
||||
os_printf("ui_s->label_time:%X\n", ui_s->label_time);
|
||||
lv_label_set_text(ui_s->label_time, "00:00");
|
||||
|
||||
// 重新打开一个视频文件
|
||||
char path[64];
|
||||
const char *filename = lv_list_get_btn_text(list, list_item);
|
||||
os_printf("play filename:%s\n", filename);
|
||||
os_sprintf(path, "0:%s/%s", CHECK_DIR, filename);
|
||||
|
||||
ui_s->play_name = (uint8_t *) STREAM_MALLOC(PLAY_AVI_STREAM_NAME);
|
||||
os_sprintf((char *) ui_s->play_name, "%s_%04d", filename, (uint32_t) os_jiffies());
|
||||
os_printf("struct msi play_name:%s addr:0x%x\n", ui_s->play_name, ui_s->play_name);
|
||||
ui_s->mp4_s = mp4_demux_msi_init((const char *) ui_s->play_name, (const char *) path);
|
||||
if (ui_s->mp4_s)
|
||||
{
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
#if AUDIO_EN
|
||||
AUDEC_INIT audec_init;
|
||||
audec_init.track_type = MEDIA_TRACK;
|
||||
audec_init.priority = play_interruptible;
|
||||
audec_init.direct_to_dac = 1;
|
||||
audec_init.use_tpc = 0;
|
||||
audec_init.destroy_self = 0;
|
||||
audec_init.src_msi = ui_s->mp4_s;
|
||||
ui_s->aac_msi = audio_decode_init(AAC_DEC, 0, &audec_init);
|
||||
#endif
|
||||
// 文件开始解析
|
||||
msi_add_output(ui_s->mp4_s, NULL, ui_s->P0_jpg_msi->name);
|
||||
msi_do_cmd(ui_s->mp4_s, MSI_CMD_VIDEO_DEMUX_CTRL, MSI_VIDEO_DEMUX_START, 0);
|
||||
ui_s->start = 1;
|
||||
}
|
||||
exit_show_filelist(e);
|
||||
}
|
||||
|
||||
static int mp4_list_show(const char *filename, void *data)
|
||||
{
|
||||
struct avi_list_param *param = (struct avi_list_param *) data;
|
||||
lv_obj_t *btn = lv_list_add_btn(param->ui, NULL, (const char *) filename);
|
||||
btn->user_data = (void *) param->ui;
|
||||
if (param->group)
|
||||
{
|
||||
lv_group_add_obj(param->group, btn);
|
||||
}
|
||||
|
||||
// 回调函数,进入回放功能
|
||||
lv_obj_add_event_cb(btn, enter_playback, LV_EVENT_CLICKED, param->ui_s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 遍历文件夹
|
||||
static int each_read_file(creat_avi_list_ui fn, void *param)
|
||||
{
|
||||
DIR dir;
|
||||
FILINFO finfo;
|
||||
FRESULT fr;
|
||||
if (!fn)
|
||||
{
|
||||
goto each_read_file_end;
|
||||
}
|
||||
|
||||
fr = f_findfirst(&dir, &finfo, CHECK_DIR, EXT_NAME);
|
||||
|
||||
while (fr == FR_OK && finfo.fname[0] != 0)
|
||||
{
|
||||
fn(finfo.fname, param);
|
||||
fr = f_findnext(&dir, &finfo);
|
||||
}
|
||||
|
||||
f_closedir(&dir);
|
||||
each_read_file_end:
|
||||
os_printf("%s:%d\tret:%d\n", __FUNCTION__, __LINE__, fr);
|
||||
return fr;
|
||||
}
|
||||
|
||||
static void clear_list_group_ui(lv_event_t *e)
|
||||
{
|
||||
lv_group_t *group = (lv_group_t *) lv_event_get_user_data(e);
|
||||
os_printf("group:%X\n", group);
|
||||
if (group)
|
||||
{
|
||||
lv_group_del(group);
|
||||
}
|
||||
}
|
||||
|
||||
static void show_filelist(lv_event_t *e)
|
||||
{
|
||||
int32_t c = *((int32_t *) lv_event_get_param(e));
|
||||
if (c == 'e')
|
||||
{
|
||||
set_lvgl_get_key_func(NULL);
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
struct avi_list_param param;
|
||||
lv_obj_t *list = lv_list_create(ui_s->now_ui);
|
||||
lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
|
||||
param.ui_s = ui_s;
|
||||
param.ui = list;
|
||||
param.group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, param.group);
|
||||
// 创建exit的控件
|
||||
lv_obj_t *list_item = lv_list_add_btn(list, NULL, "exit");
|
||||
list_item->user_data = (void *) list;
|
||||
lv_group_add_obj(param.group, list_item);
|
||||
lv_obj_add_event_cb(list_item, exit_show_filelist, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
|
||||
each_read_file(mp4_list_show, (void *) ¶m);
|
||||
|
||||
lv_obj_add_event_cb(list, clear_list_group_ui, LV_EVENT_DELETE, param.group);
|
||||
}
|
||||
}
|
||||
|
||||
static void player_locate_ctrl_ui(lv_event_t *e)
|
||||
{
|
||||
// struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
int32_t c = *((int32_t *) lv_event_get_param(e));
|
||||
// printf("c:%d\n",c);
|
||||
switch (c)
|
||||
{
|
||||
// 后退
|
||||
case 'a':
|
||||
{
|
||||
}
|
||||
|
||||
break;
|
||||
// 前进
|
||||
case 'd':
|
||||
{
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void player_ctrl_ui(lv_event_t *e)
|
||||
{
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
if (ui_s->mp4_s)
|
||||
{
|
||||
ui_s->start++;
|
||||
|
||||
if (ui_s->start)
|
||||
{
|
||||
msi_do_cmd(ui_s->mp4_s, MSI_CMD_VIDEO_DEMUX_CTRL, MSI_VIDEO_DEMUX_START, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
msi_do_cmd(ui_s->mp4_s, MSI_CMD_VIDEO_DEMUX_CTRL, MSI_VIDEO_DEMUX_PAUSE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void exit_player_ui(lv_event_t *e)
|
||||
{
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
int32_t c = *((int32_t *) lv_event_get_param(e));
|
||||
if (c == 'q')
|
||||
{
|
||||
lv_timer_del(ui_s->timer);
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_destroy(ui_s->P0_jpg_msi);
|
||||
msi_destroy(ui_s->decode_msi);
|
||||
if (ui_s->mp4_s)
|
||||
{
|
||||
msi_destroy(ui_s->mp4_s);
|
||||
ui_s->mp4_s = NULL;
|
||||
}
|
||||
|
||||
#if AUDIO_EN
|
||||
if (ui_s->aac_msi)
|
||||
{
|
||||
// msi_destroy(ui_s->aac_msi);
|
||||
audio_decode_deinit(ui_s->aac_msi);
|
||||
ui_s->aac_msi = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ui_s->mp4_s = NULL;
|
||||
ui_s->decode_msi = NULL;
|
||||
ui_s->P0_jpg_msi = NULL;
|
||||
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
if (ui_s->play_name)
|
||||
{
|
||||
STREAM_FREE(ui_s->play_name);
|
||||
ui_s->play_name = NULL;
|
||||
}
|
||||
set_lvgl_get_key_func(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void player_ui_timer(lv_timer_t *t)
|
||||
{
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) t->user_data;
|
||||
if (ui_s->mp4_s)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static void enter_player_ui(lv_event_t *e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
// demo主要是h264的解码,所以这里初始化一下
|
||||
h264_drv_init();
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) lv_event_get_user_data(e);
|
||||
lv_obj_t *base_ui = ui_s->base_ui;
|
||||
lv_obj_add_flag(base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
// SR_OTHER_JPG接收数据,然后发送到decode
|
||||
ui_s->P0_jpg_msi = h264_decode_msg_msi(SR_OTHER_JPG, ui_s->w, ui_s->h, ui_s->w, ui_s->h, 0);
|
||||
if (ui_s->P0_jpg_msi)
|
||||
{
|
||||
|
||||
msi_do_cmd(ui_s->P0_jpg_msi, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_FORCE_TYPE, FSTYPE_YUV_P0);
|
||||
ui_s->P0_jpg_msi->enable = 1;
|
||||
}
|
||||
|
||||
// decode发送到S_NEWPLAYER控制速度后,转发到P0
|
||||
ui_s->decode_msi = h264_decode_msi("h264_decode", 0);
|
||||
if (ui_s->decode_msi)
|
||||
{
|
||||
msi_add_output(ui_s->P0_jpg_msi, NULL, ui_s->decode_msi->name);
|
||||
msi_add_output(ui_s->decode_msi, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->decode_msi->enable = 1;
|
||||
}
|
||||
|
||||
// 创建lvgl的timer,用于获取播放的时间
|
||||
|
||||
ui_s->label_time = lv_label_create(ui);
|
||||
lv_label_set_text(ui_s->label_time, "00:00");
|
||||
lv_obj_align(ui_s->label_time, LV_ALIGN_TOP_MID, 0, 0);
|
||||
ui_s->timer = lv_timer_create(player_ui_timer, 100, (void *) ui_s);
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_player_ui, LV_EVENT_KEY, ui_s);
|
||||
// 控制暂停、播放
|
||||
lv_obj_add_event_cb(ui, player_ctrl_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
|
||||
// 快进快退,一次尝试快进5秒,一次尝试快退5秒
|
||||
lv_obj_add_event_cb(ui, player_locate_ctrl_ui, LV_EVENT_KEY, ui_s);
|
||||
|
||||
// 弹出菜单栏,用于切换分辨率
|
||||
lv_obj_add_event_cb(ui, show_filelist, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *mp4_player_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h)
|
||||
{
|
||||
struct mp4_player_ui_s *ui_s = (struct mp4_player_ui_s *) STREAM_LIBC_ZALLOC(sizeof(struct mp4_player_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
ui_s->play_name = NULL;
|
||||
ui_s->w = w;
|
||||
ui_s->h = h;
|
||||
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "mp4_player");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_player_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
259
sdk/app/ui/mp4_recorder_ui.c
Normal file
259
sdk/app/ui/mp4_recorder_ui.c
Normal file
@@ -0,0 +1,259 @@
|
||||
/***************************************************************************************
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "audio_msi/audio_adc.h"
|
||||
#include "audio_media_ctrl/audio_code_ctrl.h"
|
||||
#include "file_process.h"
|
||||
#include "fs/fatfs/osal_file.h"
|
||||
#include "file_process.h"
|
||||
#define RECORDER_DIR "0:MP4"
|
||||
|
||||
struct msi *mp4_encode_msi2_init(const char *mp4_msi_name, uint8_t srcID, uint8_t filter_type, uint8_t rec_time, uint32_t audio_encode, struct file_process *file_process, uint8_t mode);
|
||||
|
||||
#define LVGL_MP4_MSI_NAME "lvgl_mp4"
|
||||
#define LV_OBJ_MP4_RECORD_FLAG LV_OBJ_FLAG_USER_1
|
||||
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_indev_t *indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
|
||||
struct mp4_record_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
uint16_t w, h;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
lv_timer_t *timer;
|
||||
lv_obj_t *label_time;
|
||||
|
||||
struct msi *s;
|
||||
struct msi *h264_msi;
|
||||
struct msi *mp4_msi;
|
||||
struct msi *aac_msi;
|
||||
|
||||
uint8_t *play_name;
|
||||
uint8_t start : 1, rev : 7;
|
||||
};
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if (val > 0)
|
||||
{
|
||||
if ((val & 0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch (val >> 8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'a';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'd';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
static void *lvgl_mp4_file(struct file_process *file_process, char *filename, char *file_path, uint32_t file_size)
|
||||
{
|
||||
os_sprintf(filename, "%s/%016d.mp4", file_process->rec_path, (uint32_t) os_jiffies());
|
||||
void *fp = osal_fopen_auto((const char *) filename, "w+", 0);
|
||||
return fp;
|
||||
}
|
||||
|
||||
static void start_mp4_record_ui(lv_event_t *e)
|
||||
{
|
||||
int32_t c = *((int32_t *) lv_event_get_param(e));
|
||||
struct mp4_record_ui_s *ui_s = (struct mp4_record_ui_s *) lv_event_get_user_data(e);
|
||||
if (c == LV_KEY_ENTER)
|
||||
{
|
||||
if (!lv_obj_has_flag(ui_s->now_ui, LV_OBJ_MP4_RECORD_FLAG))
|
||||
{
|
||||
os_printf("%s:%d\n", __FUNCTION__, __LINE__);
|
||||
ui_s->h264_msi = msi_find(AUTO_H264, 1);
|
||||
if (ui_s->h264_msi)
|
||||
{
|
||||
lv_obj_add_flag(ui_s->now_ui, LV_OBJ_MP4_RECORD_FLAG);
|
||||
struct file_process mp4_file_process = {
|
||||
.loop = NULL,
|
||||
.rec_path = RECORDER_DIR,
|
||||
.ext_name = ".MP4",
|
||||
.create_file = lvgl_mp4_file,
|
||||
.loop_free = NULL,
|
||||
.lock_file = NULL,
|
||||
};
|
||||
uint8_t audio_flag = 0;
|
||||
AUENC_INIT auenc_init;
|
||||
auenc_init.destroy_self = 0;
|
||||
auenc_init.src_msi = get_auadc_msi(AUSYS_AUAD);
|
||||
ui_s->aac_msi = audio_encode_init(AAC_ENC, audio_adc_get_samplerate(AUSYS_AUAD), &auenc_init);
|
||||
if (ui_s->aac_msi)
|
||||
{
|
||||
audio_code_add_output(ui_s->aac_msi, LVGL_MP4_MSI_NAME);
|
||||
audio_flag = 1;
|
||||
}
|
||||
|
||||
ui_s->mp4_msi = mp4_encode_msi2_init(LVGL_MP4_MSI_NAME, FRAMEBUFF_SOURCE_CAMERA0, FSTYPE_H264_VPP_DATA0, 1, audio_flag, &mp4_file_process, 0);
|
||||
|
||||
if (ui_s->mp4_msi)
|
||||
{
|
||||
msi_do_cmd(ui_s->mp4_msi, MSI_CMD_MEDIA_CTRL, MSI_MEDIA_CTRL_RECORD_START, 0);
|
||||
msi_add_output(ui_s->h264_msi, NULL, LVGL_MP4_MSI_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui_s->aac_msi)
|
||||
{
|
||||
audio_code_del_output(ui_s->aac_msi, LVGL_MP4_MSI_NAME);
|
||||
audio_encode_deinit(ui_s->aac_msi);
|
||||
ui_s->aac_msi = NULL;
|
||||
}
|
||||
|
||||
if (ui_s->h264_msi)
|
||||
{
|
||||
msi_del_output(ui_s->h264_msi, NULL, LVGL_MP4_MSI_NAME);
|
||||
msi_put(ui_s->h264_msi);
|
||||
ui_s->h264_msi = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui_s->mp4_msi)
|
||||
{
|
||||
msi_destroy(ui_s->mp4_msi);
|
||||
ui_s->mp4_msi = NULL;
|
||||
}
|
||||
if (ui_s->aac_msi)
|
||||
{
|
||||
audio_code_del_output(ui_s->aac_msi, LVGL_MP4_MSI_NAME);
|
||||
audio_encode_deinit(ui_s->aac_msi);
|
||||
ui_s->aac_msi = NULL;
|
||||
}
|
||||
|
||||
if (ui_s->h264_msi)
|
||||
{
|
||||
msi_del_output(ui_s->h264_msi, NULL, LVGL_MP4_MSI_NAME);
|
||||
msi_put(ui_s->h264_msi);
|
||||
ui_s->h264_msi = NULL;
|
||||
}
|
||||
lv_obj_clear_flag(ui_s->now_ui, LV_OBJ_MP4_RECORD_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void exit_mp4_record_ui(lv_event_t *e)
|
||||
{
|
||||
int32_t c = *((int32_t *) lv_event_get_param(e));
|
||||
if (c == 'q')
|
||||
{
|
||||
struct mp4_record_ui_s *ui_s = (struct mp4_record_ui_s *) lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
if(ui_s->s)
|
||||
{
|
||||
msi_do_cmd(ui_s->s, MSI_CMD_SCALE3_NORMAL, MSI_SCALE3_START, 0);
|
||||
}
|
||||
msi_destroy(ui_s->s);
|
||||
// 关闭VIDEO P0的使能,释放占住的scale3的fb
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
|
||||
if (ui_s->mp4_msi)
|
||||
{
|
||||
msi_destroy(ui_s->mp4_msi);
|
||||
ui_s->mp4_msi = NULL;
|
||||
}
|
||||
if (ui_s->aac_msi)
|
||||
{
|
||||
audio_code_del_output(ui_s->aac_msi, LVGL_MP4_MSI_NAME);
|
||||
audio_encode_deinit(ui_s->aac_msi);
|
||||
ui_s->aac_msi = NULL;
|
||||
}
|
||||
|
||||
if (ui_s->h264_msi)
|
||||
{
|
||||
msi_del_output(ui_s->h264_msi, NULL, LVGL_MP4_MSI_NAME);
|
||||
msi_put(ui_s->h264_msi);
|
||||
ui_s->h264_msi = NULL;
|
||||
}
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
set_lvgl_get_key_func(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void enter_mp4_record_ui(lv_event_t *e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct mp4_record_ui_s *ui_s = (struct mp4_record_ui_s *) lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
// 绑定流到Video_P0显示
|
||||
|
||||
ui_s->s = scale3_normal_msi2(S_PREVIEW_SCALE3, FSTYPE_YUV_P0, ui_s->w, ui_s->h);
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_do_cmd(ui_s->s, MSI_CMD_SCALE3_NORMAL, MSI_SCALE3_START, 0x01);
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
|
||||
lv_obj_add_event_cb(ui, start_mp4_record_ui, LV_EVENT_KEY, ui_s);
|
||||
lv_obj_add_event_cb(ui, exit_mp4_record_ui, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *mp4_record_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h)
|
||||
{
|
||||
struct mp4_record_ui_s *ui_s = (struct mp4_record_ui_s *) STREAM_LIBC_ZALLOC(sizeof(struct mp4_record_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
ui_s->w = w;
|
||||
ui_s->h = h;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "mp4_record_ui");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_mp4_record_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
435
sdk/app/ui/photo_ui.c
Normal file
435
sdk/app/ui/photo_ui.c
Normal file
@@ -0,0 +1,435 @@
|
||||
/***************************************************************************************
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "fatfs/osal_file.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
|
||||
#define CHECK_DIR "photo"
|
||||
#define EXT_NAME "*jpg"
|
||||
|
||||
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
extern lv_style_t g_style;
|
||||
extern lv_indev_t * indev_keypad;
|
||||
|
||||
struct photo_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
|
||||
struct msi *photo_s;
|
||||
struct fbpool tx_pool;
|
||||
struct msi *other_s;
|
||||
struct msi *decode_s;
|
||||
lv_obj_t * label_path;
|
||||
|
||||
};
|
||||
|
||||
struct photo_list_param
|
||||
{
|
||||
lv_group_t *group;
|
||||
lv_obj_t *ui;
|
||||
struct photo_ui_s *ui_s;
|
||||
};
|
||||
typedef int (*list_ui)(const char *filename,void *data);
|
||||
|
||||
|
||||
|
||||
|
||||
static void exit_show_filelist(lv_event_t * e)
|
||||
{
|
||||
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_t *list_item = lv_event_get_current_target(e);
|
||||
if(ui_s->now_group)
|
||||
{
|
||||
lv_indev_set_group(indev_keypad, ui_s->now_group);
|
||||
}
|
||||
if(list_item->user_data)
|
||||
{
|
||||
//由于是子控件回调函数需要删除父控件,所以需要用到异步删除,否则删除内部链表会有异常
|
||||
lv_obj_del_async(list_item->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//读取图片,发送出去显示
|
||||
static void play_photo(lv_event_t * e)
|
||||
{
|
||||
void *fp = NULL;
|
||||
void *photo_buf = NULL;
|
||||
struct framebuff *data_s = NULL;
|
||||
uint32_t len;
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_t *list_item = lv_event_get_current_target(e);
|
||||
lv_obj_t *list = list_item->user_data;
|
||||
char path[64];
|
||||
const char *filename = lv_list_get_btn_text(list,list_item);
|
||||
os_sprintf(path,"0:%s/%s",CHECK_DIR,filename);
|
||||
if(!ui_s->photo_s)
|
||||
{
|
||||
goto play_photo_fail;
|
||||
}
|
||||
|
||||
//读取图片文件,通过流去发送
|
||||
data_s = fbpool_get(&ui_s->tx_pool, 0, ui_s->photo_s);
|
||||
if(data_s)
|
||||
{
|
||||
data_s->data = NULL;
|
||||
lv_label_set_text(ui_s->label_path, path);
|
||||
//开始显示图片
|
||||
fp = osal_fopen(path,"rb");
|
||||
if(fp)
|
||||
{
|
||||
uint32_t filesize = osal_fsize(fp);
|
||||
photo_buf = (void*)STREAM_MALLOC(filesize);
|
||||
if(!photo_buf)
|
||||
{
|
||||
msi_delete_fb(ui_s->photo_s, data_s);
|
||||
data_s = NULL;
|
||||
goto play_photo_fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = osal_fread(photo_buf,1,filesize,fp);
|
||||
if(len != filesize)
|
||||
{
|
||||
goto play_photo_fail;
|
||||
}
|
||||
data_s->data = (void*)photo_buf;
|
||||
data_s->mtype = F_JPG;
|
||||
data_s->stype = FSTYPE_YUV_P0;
|
||||
data_s->len = filesize;
|
||||
|
||||
msi_output_fb(ui_s->photo_s, data_s);
|
||||
photo_buf = NULL;
|
||||
data_s = NULL;
|
||||
goto play_photo_end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
goto play_photo_fail;
|
||||
|
||||
}
|
||||
play_photo_fail:
|
||||
//显示失败
|
||||
os_sprintf(path,"0:%s/%s fail",CHECK_DIR,filename);
|
||||
lv_label_set_text(ui_s->label_path, path);
|
||||
if(photo_buf)
|
||||
{
|
||||
STREAM_FREE(photo_buf);
|
||||
photo_buf = NULL;
|
||||
}
|
||||
if(data_s)
|
||||
{
|
||||
msi_delete_fb(NULL, data_s);
|
||||
}
|
||||
|
||||
play_photo_end:
|
||||
if(fp)
|
||||
{
|
||||
osal_fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
exit_show_filelist(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int photo_list_show(const char *filename,void *data)
|
||||
{
|
||||
struct photo_list_param *param = (struct photo_list_param*)data;
|
||||
lv_obj_t * btn = lv_list_add_btn(param->ui, NULL, (const char *)filename);
|
||||
btn->user_data = (void*)param->ui;
|
||||
if(param->group)
|
||||
{
|
||||
lv_group_add_obj(param->group, btn);
|
||||
}
|
||||
|
||||
//回调函数,进入回放功能
|
||||
lv_obj_add_event_cb(btn, play_photo, LV_EVENT_CLICKED, param->ui_s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//遍历文件夹
|
||||
//遍历文件夹
|
||||
static int each_read_file(list_ui fn,void *param)
|
||||
{
|
||||
DIR dir;
|
||||
FILINFO finfo;
|
||||
FRESULT fr;
|
||||
if(!fn)
|
||||
{
|
||||
goto each_read_file_end;
|
||||
}
|
||||
|
||||
fr = f_findfirst(&dir, &finfo, CHECK_DIR, EXT_NAME);
|
||||
|
||||
|
||||
while(fr == FR_OK && finfo.fname[0] != 0)
|
||||
{
|
||||
fn(finfo.fname,param);
|
||||
fr = f_findnext(&dir, &finfo);
|
||||
}
|
||||
|
||||
f_closedir(&dir);
|
||||
each_read_file_end:
|
||||
os_printf("%s:%d\tret:%d\n",__FUNCTION__,__LINE__,fr);
|
||||
return fr;
|
||||
}
|
||||
|
||||
static void clear_list_group_ui(lv_event_t * e)
|
||||
{
|
||||
lv_group_t *group = (lv_group_t *)lv_event_get_user_data(e);
|
||||
os_printf("group:%X\n",group);
|
||||
if(group)
|
||||
{
|
||||
lv_group_del(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void show_filelist(lv_event_t * e)
|
||||
{
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'e')
|
||||
{
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s *)lv_event_get_user_data(e);
|
||||
struct photo_list_param param;
|
||||
lv_obj_t *list = lv_list_create(ui_s->now_ui);
|
||||
lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
|
||||
param.ui_s = ui_s;
|
||||
param.ui = list;
|
||||
param.group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, param.group);
|
||||
//创建exit的控件
|
||||
lv_obj_t *list_item = lv_list_add_btn(list, NULL, "exit");
|
||||
list_item->user_data = (void*)list;
|
||||
lv_group_add_obj(param.group, list_item);
|
||||
lv_obj_add_event_cb(list_item, exit_show_filelist, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
|
||||
each_read_file(photo_list_show,(void*)¶m);
|
||||
|
||||
lv_obj_add_event_cb(list, clear_list_group_ui, LV_EVENT_DELETE, param.group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if(val > 0)
|
||||
{
|
||||
if((val&0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch(val>>8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = LV_KEY_PREV;
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = LV_KEY_NEXT;
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
static int32 photo_msi_action(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2)
|
||||
{
|
||||
int32_t ret = RET_OK;
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s *)msi->priv;
|
||||
|
||||
switch (cmd_id)
|
||||
{
|
||||
case MSI_CMD_PRE_DESTROY:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
fbpool_destroy(&ui_s->tx_pool);
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
struct framebuff *fb = (struct framebuff *)param1;
|
||||
if (fb->data)
|
||||
{
|
||||
STREAM_FREE(fb->data);
|
||||
fb->data = NULL;
|
||||
}
|
||||
fbpool_put(&ui_s->tx_pool, fb);
|
||||
ret = RET_OK + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//创建播放器的流,这个流主要实现的是控制速度转发作用,暂时控制的是视频
|
||||
//如果要控制音频,需要计算时间来控制速度
|
||||
static struct msi *photo_stream(const char *name)
|
||||
{
|
||||
struct msi *s = msi_new(name, 0, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void exit_player_ui(lv_event_t * e)
|
||||
{
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'q')
|
||||
{
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_destroy(ui_s->photo_s);
|
||||
msi_destroy(ui_s->other_s);
|
||||
msi_destroy(ui_s->decode_s);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
|
||||
ui_s->decode_s = NULL;
|
||||
ui_s->other_s = NULL;
|
||||
ui_s->photo_s = NULL;
|
||||
|
||||
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
|
||||
set_lvgl_get_key_func(NULL);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void enter_player_ui(lv_event_t * e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_t *base_ui = ui_s->base_ui;
|
||||
lv_obj_add_flag(base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
os_printf("%s ui_s:%x ui_s->decode_s:%x\n",__FUNCTION__,ui_s,&ui_s->decode_s);
|
||||
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
|
||||
ui_s->label_path = lv_label_create(ui);
|
||||
lv_label_set_text(ui_s->label_path, "");
|
||||
lv_obj_align(ui_s->label_path,LV_ALIGN_TOP_MID,0,0);
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
ui_s->photo_s = photo_stream(S_LVGL_PHOTO);
|
||||
if (ui_s->photo_s)
|
||||
{
|
||||
ui_s->photo_s->priv = (void *)ui_s;
|
||||
fbpool_init(&ui_s->tx_pool, 4);
|
||||
ui_s->photo_s->action = photo_msi_action;
|
||||
msi_add_output(ui_s->photo_s, NULL, SR_OTHER_JPG);
|
||||
ui_s->photo_s->enable = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("photo ui new msi failed\n");
|
||||
}
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
//SR_OTHER_JPG接收数据,然后发送到decode
|
||||
ui_s->other_s = jpg_decode_msg_msi(SR_OTHER_JPG,640,360,640,360,FSTYPE_YUV_P0);
|
||||
if (ui_s->other_s)
|
||||
{
|
||||
msi_add_output(ui_s->other_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
//decode发送到S_NEWPLAYER控制速度后,转发到P0
|
||||
ui_s->decode_s = jpg_decode_msi(S_JPG_DECODE);
|
||||
if (ui_s->decode_s)
|
||||
{
|
||||
msi_add_output(ui_s->decode_s, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
}
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
|
||||
//弹出菜单栏,用于切换分辨率
|
||||
lv_obj_add_event_cb(ui, show_filelist, LV_EVENT_KEY, ui_s);
|
||||
lv_obj_add_event_cb(ui, exit_player_ui, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *photo_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct photo_ui_s *ui_s = (struct photo_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct photo_ui_s));
|
||||
os_printf("%s ui_s:%x ui_s->decode_s:%x\n",__FUNCTION__,ui_s,&ui_s->decode_s);
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "photo");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_player_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
152
sdk/app/ui/preview_dvp_csi_usb_ui.c
Normal file
152
sdk/app/ui/preview_dvp_csi_usb_ui.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/***********************************************************************************************************
|
||||
这个主要是 dvp + csi + uvc(mjpeg) 实现视频预览,最多支持4个视频源输出预览
|
||||
|
||||
S_PREVIEW_SCALE3 ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(scale3) (虚拟屏幕)
|
||||
|
||||
/dev/video0 ----> ROUTE_USB ----> SR_OTHER_JPG_USB1 ----> S_JPG_DECODE ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(uvc) (uvc中转流) (uvc的jpg,配置解码size) (解码成yuv:320x180) (虚拟屏幕)
|
||||
|
||||
|
||||
/dev/video1 ----> ROUTE_USB ----> SR_OTHER_JPG_USB2 ----> S_JPG_DECODE ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(uvc) (uvc中转流) (uvc的jpg,配置解码size) (解码成yuv:320x180) (虚拟屏幕)
|
||||
|
||||
********************************************************************************************************** */
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct preview_usb_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
//这个是需要的流,但命名不一定对应,有可能通过中间流进行中转实现
|
||||
struct msi *sim_video;
|
||||
struct msi *scale3_s;
|
||||
struct msi *decode_s;
|
||||
struct msi *USB_P0_jpg_s;
|
||||
struct msi *USB_P1_jpg_s;
|
||||
struct msi *route_usb_msi;
|
||||
|
||||
};
|
||||
|
||||
static void exit_preview_dvp_csi_usb_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_usb_s *ui_s = (struct preview_usb_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_destroy(ui_s->route_usb_msi);
|
||||
msi_destroy(ui_s->sim_video);
|
||||
msi_destroy(ui_s->scale3_s);
|
||||
msi_destroy(ui_s->decode_s);
|
||||
msi_destroy(ui_s->USB_P0_jpg_s);
|
||||
msi_destroy(ui_s->USB_P1_jpg_s);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_preview_dvp_csi_usb_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_usb_s *ui_s = (struct preview_usb_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
|
||||
static const uint16_t filter[] = { FSTYPE_YUV_P0, FSTYPE_YUV_P1, FSTYPE_YUV_SIM_P0, FSTYPE_USB_CAM0, FSTYPE_USB_CAM1, FSTYPE_NONE };
|
||||
ui_s->sim_video = sim_video_more_msi(R_SIM_VIDEO, 800, 480, (uint16_t*)filter);
|
||||
if (ui_s->sim_video)
|
||||
{
|
||||
msi_add_output(ui_s->sim_video, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
}
|
||||
|
||||
|
||||
ui_s->scale3_s = scale3_msi(S_PREVIEW_SCALE3);
|
||||
//绑定流到Video P1显示
|
||||
if (ui_s->scale3_s)
|
||||
{
|
||||
msi_add_output(ui_s->scale3_s, NULL, R_SIM_VIDEO);
|
||||
}
|
||||
|
||||
|
||||
ui_s->decode_s = jpg_decode_msi(S_JPG_DECODE);
|
||||
//将解码的数据推送到Video P0
|
||||
if (ui_s->decode_s)
|
||||
{
|
||||
msi_add_output(ui_s->decode_s, NULL, R_SIM_VIDEO);
|
||||
}
|
||||
|
||||
|
||||
//接收UVC的jpg,配置解码需要的参数(320x180),最后给到解码模块
|
||||
ui_s->USB_P0_jpg_s = jpg_decode_msg_msi(SR_OTHER_JPG_USB1,320,180,320,180,FSTYPE_USB_CAM0);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (ui_s->USB_P0_jpg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(ui_s->USB_P0_jpg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 0 << 16 | 220);
|
||||
msi_add_output(ui_s->USB_P0_jpg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
|
||||
//接收usb的jpg数据,配置需要解码的参数(320x180),然后给到S_JPG_DECODE进行解码,最后给到P1去显示(设置时P1的类型)
|
||||
ui_s->USB_P1_jpg_s = jpg_decode_msg_msi(SR_OTHER_JPG_USB2,320,180,320,180,FSTYPE_USB_CAM1);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (ui_s->USB_P1_jpg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(ui_s->USB_P1_jpg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 360 << 16 | 220);
|
||||
msi_add_output(ui_s->USB_P1_jpg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
|
||||
ui_s->route_usb_msi = route_msi(ROUTE_USB);
|
||||
if (ui_s->route_usb_msi)
|
||||
{
|
||||
msi_add_output(ui_s->route_usb_msi, NULL, SR_OTHER_JPG_USB1);
|
||||
msi_add_output(ui_s->route_usb_msi, NULL, SR_OTHER_JPG_USB2);
|
||||
}
|
||||
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_preview_dvp_csi_usb_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *preview_dvp_csi_usb_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct preview_usb_s *ui_s = (struct preview_usb_s*)STREAM_LIBC_ZALLOC(sizeof(struct preview_usb_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "preview_dvp_csi_usb");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_preview_dvp_csi_usb_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
288
sdk/app/ui/preview_encode_takephoto_ui.c
Normal file
288
sdk/app/ui/preview_encode_takephoto_ui.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/***************************************************************************************
|
||||
S_PREVIEW_SCALE3 ----> R_VIDEO_P0(320x180)
|
||||
(scale3) (lcd_video_p0)
|
||||
|
||||
RS_JPG_CONCAT ----> R_LVGL_TAKEPHOTO(1280x720)
|
||||
(mjpeg)
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "keyWork.h"
|
||||
#include "keyScan.h"
|
||||
#include "fatfs/osal_file.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
#define LV_OBJ_TAKEPHOTO_FLAG LV_OBJ_FLAG_USER_1
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
|
||||
struct preview_encode_takephoto_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
lv_timer_t *timer;
|
||||
|
||||
struct msi *s;
|
||||
struct msi *jpg_s;
|
||||
struct msi *takephoto_s;
|
||||
};
|
||||
|
||||
|
||||
static uint32_t self_key(uint32_t val)
|
||||
{
|
||||
uint32_t key_ret = 0;
|
||||
if(val > 0)
|
||||
{
|
||||
if((val&0xff) == KEY_EVENT_SUP)
|
||||
{
|
||||
switch(val>>8)
|
||||
{
|
||||
case AD_UP:
|
||||
key_ret = 'a';
|
||||
break;
|
||||
case AD_DOWN:
|
||||
key_ret = 's';
|
||||
break;
|
||||
case AD_LEFT:
|
||||
key_ret = 'q';
|
||||
break;
|
||||
case AD_RIGHT:
|
||||
key_ret = 'd';
|
||||
break;
|
||||
case AD_PRESS:
|
||||
key_ret = LV_KEY_ENTER;
|
||||
break;
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if((val&0xff) == KEY_EVENT_LUP)
|
||||
{
|
||||
|
||||
|
||||
switch(val>>8)
|
||||
{
|
||||
case AD_PRESS:
|
||||
key_ret = 'e';
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return key_ret;
|
||||
}
|
||||
|
||||
|
||||
//生成一个流,专门接收图片,用于拍照的,拍照之前可以将缓冲区的删除,这样可以保证得到最新的图片
|
||||
//要考虑一些问题,如果拍照放在workqueue,要考虑写卡时间是否影响workqueue
|
||||
//这里尝试使用lvgl的timer事件去保存(影响lvgl,如果需要更加好,可能要创建任务去保存)
|
||||
|
||||
static int32 takephoto_msi_action(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2)
|
||||
{
|
||||
int32_t ret = RET_OK;
|
||||
//struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s *)msi->priv;
|
||||
|
||||
switch (cmd_id)
|
||||
{
|
||||
case MSI_CMD_PRE_DESTROY:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct msi *takephoto_stream(const char *name)
|
||||
{
|
||||
//设置接收1,是为了不要接收太多的图片,因为是拍照,需要保持实时性
|
||||
//如果接收过多,如果不处理,会导致源头没有空间产生新的图片
|
||||
//如果要结合录像,则需要在应用层去处理(实际录像时可以创建另一个独立的流)
|
||||
struct msi *msi = msi_new(name, 1, NULL);
|
||||
return msi;
|
||||
}
|
||||
|
||||
static void takephoto_timer(lv_timer_t *t)
|
||||
{
|
||||
struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s *)t->user_data;
|
||||
struct framebuff *fb = NULL;
|
||||
//看看对应的流有没有图片,如果有,则保存
|
||||
fb = msi_get_fb(ui_s->takephoto_s, 0);
|
||||
if(fb)
|
||||
{
|
||||
ui_s->takephoto_s->enable = 0;
|
||||
char filename[64];
|
||||
sprintf(filename,"0:/photo/%08d.jpg",(uint32_t)os_jiffies());
|
||||
void *fp = osal_fopen(filename,"wb");
|
||||
if(fp)
|
||||
{
|
||||
osal_fwrite(fb->data,1,fb->len,fp);
|
||||
osal_fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("takephoto fail,filename:%s\n",filename);
|
||||
}
|
||||
//保存图片
|
||||
msi_delete_fb(NULL, fb);
|
||||
|
||||
while(fb)
|
||||
{
|
||||
fb = msi_get_fb(ui_s->takephoto_s, 0);
|
||||
if(fb)
|
||||
{
|
||||
msi_delete_fb(NULL, fb);
|
||||
}
|
||||
}
|
||||
os_printf("takephoto success\n");
|
||||
lv_obj_clear_flag(ui_s->now_ui, LV_OBJ_TAKEPHOTO_FLAG);
|
||||
ui_s->timer = NULL;
|
||||
lv_timer_del(t);
|
||||
}
|
||||
}
|
||||
|
||||
//使能拍照
|
||||
static void encode_takephoto_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s *)lv_event_get_user_data(e);
|
||||
struct msi *s = ui_s->takephoto_s;
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == LV_KEY_ENTER)
|
||||
{
|
||||
if(!lv_obj_has_flag(ui_s->now_ui,LV_OBJ_TAKEPHOTO_FLAG))
|
||||
{
|
||||
lv_obj_add_flag(ui_s->now_ui, LV_OBJ_TAKEPHOTO_FLAG);
|
||||
s->enable = 1;
|
||||
//启动timer,10ms检查一次
|
||||
ui_s->timer = lv_timer_create(takephoto_timer, 10, (void*)ui_s);
|
||||
}
|
||||
else
|
||||
{
|
||||
//已经在拍照了
|
||||
os_printf("%s already running\n",__FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void exit_preview_encode_takephoto_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s *)lv_event_get_user_data(e);
|
||||
int32_t c = *((int32_t *)lv_event_get_param(e));
|
||||
if(c == 'q')
|
||||
{
|
||||
if(ui_s->timer)
|
||||
{
|
||||
lv_timer_del(ui_s->timer);
|
||||
}
|
||||
struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_destroy(ui_s->s);
|
||||
msi_del_output(ui_s->jpg_s, NULL, R_LVGL_TAKEPHOTO);
|
||||
msi_put(ui_s->jpg_s);
|
||||
msi_destroy(ui_s->takephoto_s);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
|
||||
set_lvgl_get_key_func(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_preview_encode_takephoto_ui(lv_event_t * e)
|
||||
{
|
||||
set_lvgl_get_key_func(self_key);
|
||||
struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
ui_s->s = scale3_msi(S_PREVIEW_SCALE3);
|
||||
//绑定流到Video P0显示
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
|
||||
//创建jpg流,设置从vpp_buf0取数据
|
||||
ui_s->jpg_s = msi_find(AUTO_JPG, 1);
|
||||
if(ui_s->jpg_s)
|
||||
{
|
||||
msi_add_output(ui_s->jpg_s, NULL, R_LVGL_TAKEPHOTO);
|
||||
ui_s->jpg_s->enable = 1;
|
||||
}
|
||||
|
||||
ui_s->takephoto_s = takephoto_stream(R_LVGL_TAKEPHOTO);
|
||||
if(ui_s->takephoto_s)
|
||||
{
|
||||
ui_s->takephoto_s->action = takephoto_msi_action;
|
||||
ui_s->takephoto_s->priv = ui_s;
|
||||
}
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_preview_encode_takephoto_ui, LV_EVENT_KEY, ui_s);
|
||||
|
||||
//拍照的按键事件
|
||||
lv_obj_add_event_cb(ui, encode_takephoto_ui, LV_EVENT_KEY, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *preview_encode_takephoto_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct preview_encode_takephoto_ui_s *ui_s = (struct preview_encode_takephoto_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct preview_encode_takephoto_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "preview_encode_takephoto");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_preview_encode_takephoto_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
310
sdk/app/ui/preview_qc_ui.c
Normal file
310
sdk/app/ui/preview_qc_ui.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/***********************************************************************************************************
|
||||
这个主要是 dvp + csi + uvc(mjpeg) 实现视频预览,最多支持4个视频源输出预览
|
||||
|
||||
S_PREVIEW_SCALE3 ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(scale3) (虚拟屏幕)
|
||||
|
||||
/dev/video0 ----> ROUTE_USB ----> SR_OTHER_JPG_USB1 ----> S_JPG_DECODE ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(uvc) (uvc中转流) (uvc的jpg,配置解码size) (解码成yuv:320x180) (虚拟屏幕)
|
||||
|
||||
|
||||
S_LVGL_PHOTO ----> SR_OTHER_JPG_USB2 ----> S_JPG_DECODE ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(sd) (sd的jpg,配置解码size) (解码成yuv:320x180) (虚拟屏幕)
|
||||
|
||||
********************************************************************************************************** */
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "fatfs/osal_file.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
#define CHECK_DIR "photo"
|
||||
#define EXT_NAME "*jpg"
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct preview_qc_s
|
||||
{
|
||||
struct os_work work;
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
//这个是需要的流,但命名不一定对应,有可能通过中间流进行中转实现
|
||||
struct msi *sim_video;
|
||||
struct msi *scale3_s;
|
||||
struct msi *decode_s;
|
||||
struct msi *USB_P0_jpg_s;
|
||||
struct msi *USB_P1_jpg_s;
|
||||
struct msi *photo_s;
|
||||
struct fbpool tx_pool;
|
||||
struct msi *route_usb_msi;
|
||||
|
||||
};
|
||||
|
||||
static void play_photo(void *d)
|
||||
{
|
||||
void *fp = NULL;
|
||||
void *photo_buf = NULL;
|
||||
struct framebuff *data_s = NULL;
|
||||
struct preview_qc_s *ui_s = (struct preview_qc_s *)d;
|
||||
uint32_t len;
|
||||
char path[64];
|
||||
os_sprintf(path,"0:%s/%s",CHECK_DIR,"qc.jpg");
|
||||
if(!ui_s->photo_s)
|
||||
{
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
goto play_photo_fail;
|
||||
}
|
||||
|
||||
//读取图片文件,通过流去发送
|
||||
data_s = fbpool_get(&ui_s->tx_pool, 0, ui_s->photo_s);
|
||||
if(data_s)
|
||||
{
|
||||
data_s->data = NULL;
|
||||
//开始显示图片
|
||||
fp = osal_fopen(path,"rb");
|
||||
if(fp)
|
||||
{
|
||||
uint32_t filesize = osal_fsize(fp);
|
||||
photo_buf = (void*)STREAM_MALLOC(filesize);
|
||||
if(!photo_buf)
|
||||
{
|
||||
msi_delete_fb(ui_s->photo_s, data_s);
|
||||
data_s = NULL;
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
goto play_photo_fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = osal_fread(photo_buf,1,filesize,fp);
|
||||
if(len != filesize)
|
||||
{
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
goto play_photo_fail;
|
||||
}
|
||||
data_s->data = (void*)photo_buf;
|
||||
data_s->mtype = F_JPG;
|
||||
data_s->stype = FSTYPE_YUV_SIM_P0;
|
||||
data_s->len = filesize;
|
||||
|
||||
msi_output_fb(ui_s->photo_s, data_s);
|
||||
photo_buf = NULL;
|
||||
data_s = NULL;
|
||||
goto play_photo_end;
|
||||
}
|
||||
|
||||
}
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
goto play_photo_fail;
|
||||
|
||||
|
||||
}
|
||||
play_photo_fail:
|
||||
//显示失败
|
||||
os_sprintf(path,"0:%s/%s fail",CHECK_DIR,"qc.jpg");
|
||||
os_printf("----------------------------------------\n");
|
||||
if(photo_buf)
|
||||
{
|
||||
STREAM_FREE(photo_buf);
|
||||
}
|
||||
if(data_s)
|
||||
{
|
||||
msi_delete_fb(NULL, data_s);
|
||||
}
|
||||
|
||||
play_photo_end:
|
||||
if(fp)
|
||||
{
|
||||
osal_fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int32 photo_msi_work(struct os_work *work)
|
||||
{
|
||||
struct preview_qc_s *ui_s = (struct preview_qc_s *)work;
|
||||
play_photo(ui_s);
|
||||
os_run_work_delay(&ui_s->work, 200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 photo_msi_action(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2)
|
||||
{
|
||||
int32_t ret = RET_OK;
|
||||
struct preview_qc_s *ui_s = (struct preview_qc_s *)msi->priv;
|
||||
|
||||
switch (cmd_id)
|
||||
{
|
||||
case MSI_CMD_PRE_DESTROY:
|
||||
{
|
||||
os_work_cancle2(&ui_s->work, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
fbpool_destroy(&ui_s->tx_pool);
|
||||
os_printf("%s %d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
struct framebuff *fb = (struct framebuff *)param1;
|
||||
if (fb->data)
|
||||
{
|
||||
STREAM_FREE(fb->data);
|
||||
fb->data = NULL;
|
||||
}
|
||||
fbpool_put(&ui_s->tx_pool, fb);
|
||||
ret = RET_OK + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//创建播放器的流,这个流主要实现的是控制速度转发作用,暂时控制的是视频
|
||||
//如果要控制音频,需要计算时间来控制速度
|
||||
static struct msi *photo_stream(const char *name)
|
||||
{
|
||||
struct msi *s = msi_new(name, 0, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void exit_preview_qc_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_qc_s *ui_s = (struct preview_qc_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_destroy(ui_s->photo_s);
|
||||
msi_destroy(ui_s->route_usb_msi);
|
||||
msi_destroy(ui_s->sim_video);
|
||||
msi_destroy(ui_s->scale3_s);
|
||||
msi_destroy(ui_s->decode_s);
|
||||
msi_destroy(ui_s->USB_P0_jpg_s);
|
||||
msi_destroy(ui_s->USB_P1_jpg_s);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_preview_qc_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_qc_s *ui_s = (struct preview_qc_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
|
||||
static const uint16_t filter[] = { FSTYPE_YUV_P0, FSTYPE_YUV_P1, FSTYPE_YUV_SIM_P0, FSTYPE_USB_CAM0, FSTYPE_USB_CAM1, FSTYPE_NONE };
|
||||
ui_s->sim_video = sim_video_more_msi(R_SIM_VIDEO, 800, 480, (uint16_t*)filter);
|
||||
if (ui_s->sim_video)
|
||||
{
|
||||
msi_add_output(ui_s->sim_video, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
}
|
||||
|
||||
|
||||
ui_s->scale3_s = scale3_msi(S_PREVIEW_SCALE3);
|
||||
//绑定流到Video P1显示
|
||||
if (ui_s->scale3_s)
|
||||
{
|
||||
msi_add_output(ui_s->scale3_s, NULL, R_SIM_VIDEO);
|
||||
}
|
||||
|
||||
|
||||
ui_s->decode_s = jpg_decode_msi(S_JPG_DECODE);
|
||||
//将解码的数据推送到Video P0
|
||||
if (ui_s->decode_s)
|
||||
{
|
||||
msi_add_output(ui_s->decode_s, NULL, R_SIM_VIDEO);
|
||||
}
|
||||
|
||||
|
||||
//接收UVC的jpg,配置解码需要的参数(320x180),最后给到解码模块
|
||||
ui_s->USB_P0_jpg_s = jpg_decode_msg_msi(SR_OTHER_JPG_USB1,320,180,320,180,FSTYPE_USB_CAM0);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (ui_s->USB_P0_jpg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(ui_s->USB_P0_jpg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 0 << 16 | 220);
|
||||
msi_add_output(ui_s->USB_P0_jpg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
|
||||
ui_s->photo_s = photo_stream(S_LVGL_PHOTO);
|
||||
if (ui_s->photo_s)
|
||||
{
|
||||
ui_s->photo_s->priv = (void *)ui_s;
|
||||
fbpool_init(&ui_s->tx_pool, 4);
|
||||
ui_s->photo_s->action = photo_msi_action;
|
||||
msi_add_output(ui_s->photo_s, NULL, SR_OTHER_JPG_USB2);
|
||||
ui_s->photo_s->enable = 1;
|
||||
}
|
||||
|
||||
//接收usb的jpg数据,配置需要解码的参数(320x180),然后给到S_JPG_DECODE进行解码,最后给到P1去显示(设置时P1的类型)
|
||||
ui_s->USB_P1_jpg_s = jpg_decode_msg_msi(SR_OTHER_JPG_USB2,320,180,320,180,FSTYPE_YUV_SIM_P0);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (ui_s->USB_P1_jpg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(ui_s->USB_P1_jpg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 360 << 16 | 220);
|
||||
msi_add_output(ui_s->USB_P1_jpg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
|
||||
ui_s->route_usb_msi = route_msi(ROUTE_USB);
|
||||
if (ui_s->route_usb_msi)
|
||||
{
|
||||
msi_add_output(ui_s->route_usb_msi, NULL, SR_OTHER_JPG_USB1);
|
||||
}
|
||||
|
||||
OS_WORK_INIT(&ui_s->work, photo_msi_work, 0);
|
||||
os_run_work_delay(&ui_s->work, 1);
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_preview_qc_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *preview_qc_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct preview_qc_s *ui_s = (struct preview_qc_s*)STREAM_LIBC_ZALLOC(sizeof(struct preview_qc_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "preview_qc");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_preview_qc_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
98
sdk/app/ui/preview_sim_video.c
Normal file
98
sdk/app/ui/preview_sim_video.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/***************************************************************************************
|
||||
这个主要是预览,通过scale3_msi将dvp/csi数据scale到对应的分辨率作为数据流发送出去
|
||||
然后lcd_msi需要接收对应的数据去显示
|
||||
这里只是产生对应数据流,数据用途实际需要终端流(比如lcd流)接收后去处理
|
||||
|
||||
S_PREVIEW_SCALE3 ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(scale3) (虚拟屏幕)
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct preview_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
struct msi *s;
|
||||
struct msi *sim_video;
|
||||
|
||||
};
|
||||
|
||||
static void exit_preview_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_ui_s *ui_s = (struct preview_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_destroy(ui_s->s);
|
||||
msi_destroy(ui_s->sim_video);
|
||||
//关闭VIDEO P0,VIDEO P1的使能,释放占住的scale3的fb
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_preview_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_ui_s *ui_s = (struct preview_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
|
||||
ui_s->sim_video = sim_video_msi(R_SIM_VIDEO, 800, 480, 0);
|
||||
if (ui_s->sim_video)
|
||||
{
|
||||
msi_add_output(ui_s->sim_video, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
}
|
||||
|
||||
ui_s->s = scale3_msi(S_PREVIEW_SCALE3);
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_add_output(ui_s->s, NULL, R_SIM_VIDEO);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_preview_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *preview_sim_video_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct preview_ui_s *ui_s = (struct preview_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct preview_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "preview_sim_video");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_preview_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
104
sdk/app/ui/preview_ui.c
Normal file
104
sdk/app/ui/preview_ui.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/***************************************************************************************
|
||||
这个主要是预览,通过scale3_msi将dvp/csi数据scale到对应的分辨率作为数据流发送出去
|
||||
然后lcd_msi需要接收对应的数据去显示
|
||||
这里只是产生对应数据流,数据用途实际需要终端流(比如lcd流)接收后去处理
|
||||
|
||||
----> R_VIDEO_P0(320x240)
|
||||
| (lcd_video_p0)
|
||||
S_PREVIEW_SCALE3 -----|
|
||||
(scale3) |
|
||||
----> R_VIDEO_P1(320x240)
|
||||
(lcd_video_p1)
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_indev_t *indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct preview_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
uint16_t w, h;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
struct msi *s;
|
||||
};
|
||||
|
||||
static void exit_preview_ui(lv_event_t *e)
|
||||
{
|
||||
struct preview_ui_s *ui_s = (struct preview_ui_s *) lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_del_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_del_output(ui_s->s, NULL, R_VIDEO_P1);
|
||||
ui_s->s->enable = 0;
|
||||
if(ui_s->s)
|
||||
{
|
||||
msi_do_cmd(ui_s->s, MSI_CMD_SCALE3_NORMAL, MSI_SCALE3_START, 0);
|
||||
}
|
||||
// 关闭VIDEO P0,VIDEO P1的使能,释放占住的scale3的fb
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_destroy(ui_s->s);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
// 进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_preview_ui(lv_event_t *e)
|
||||
{
|
||||
struct preview_ui_s *ui_s = (struct preview_ui_s *) lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
// 绑定流到Video_P0,Video_P1显示
|
||||
ui_s->s = scale3_normal_msi2(S_PREVIEW_SCALE3, FSTYPE_YUV_P0, ui_s->w, ui_s->h);
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_do_cmd(ui_s->s, MSI_CMD_SCALE3_NORMAL, MSI_SCALE3_START, 1);
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P1);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_preview_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *preview_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h)
|
||||
{
|
||||
struct preview_ui_s *ui_s = (struct preview_ui_s *) STREAM_LIBC_ZALLOC(sizeof(struct preview_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
ui_s->w = w;
|
||||
ui_s->h = h;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "preview");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_preview_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
157
sdk/app/ui/preview_usb_ui.c
Normal file
157
sdk/app/ui/preview_usb_ui.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/***********************************************************************************************************
|
||||
支持双路 UVC mjpeg 镜头解码同时输出推屏,可以根据情况只显示一个
|
||||
|
||||
/dev/video0 ----> ROUTE_USB ----> SR_OTHER_JPG_USB1 ----> S_JPG_DECODE ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(uvc) (uvc中转流) (uvc的jpg,配置解码size) (解码成yuv:320x180) (虚拟屏幕)
|
||||
|
||||
|
||||
/dev/video1 ----> ROUTE_USB ----> SR_OTHER_JPG_USB2 ----> S_JPG_DECODE ----> R_SIM_VIDEO(320x180) ----> R_VIDEO_P0
|
||||
(uvc) (uvc中转流) (uvc的jpg,配置解码size) (解码成yuv:320x180) (虚拟屏幕)
|
||||
|
||||
********************************************************************************************************** */
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct preview_usb_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
//这个是需要的流,但命名不一定对应,有可能通过中间流进行中转实现
|
||||
struct msi *sim_video;
|
||||
struct msi *sim_decode_jpg_msi;
|
||||
struct msi *usb_P0_jpg_s;
|
||||
struct msi *usb_P1_jpg_s;
|
||||
struct msi *decode_s;
|
||||
|
||||
|
||||
};
|
||||
|
||||
static void exit_preview_usb_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_usb_s *ui_s = (struct preview_usb_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_destroy(ui_s->sim_video);
|
||||
msi_destroy(ui_s->sim_decode_jpg_msi);
|
||||
msi_destroy(ui_s->usb_P0_jpg_s);
|
||||
msi_destroy(ui_s->usb_P1_jpg_s);
|
||||
msi_destroy(ui_s->decode_s);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
|
||||
//进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_preview_usb_ui(lv_event_t * e)
|
||||
{
|
||||
struct preview_usb_s *ui_s = (struct preview_usb_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
ui_s->sim_decode_jpg_msi = route_msi(ROUTE_USB);
|
||||
if (ui_s->sim_decode_jpg_msi)
|
||||
{
|
||||
msi_add_output(ui_s->sim_decode_jpg_msi, NULL, SR_OTHER_JPG_USB1);
|
||||
msi_add_output(ui_s->sim_decode_jpg_msi, NULL, SR_OTHER_JPG_USB2);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("route new msi failed\n");
|
||||
}
|
||||
|
||||
static const uint16_t filter[] = { FSTYPE_USB_CAM0, FSTYPE_USB_CAM1, FSTYPE_NONE };
|
||||
ui_s->sim_video = sim_video_more_msi(R_SIM_VIDEO, 800, 480, (uint16_t *)filter);
|
||||
if (ui_s->sim_video)
|
||||
{
|
||||
msi_add_output(ui_s->sim_video, NULL, R_VIDEO_P0);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("sim video new msi failed\n");
|
||||
}
|
||||
|
||||
ui_s->decode_s = jpg_decode_msi(S_JPG_DECODE);
|
||||
//将解码的数据推送到Video P0和Video P1显示
|
||||
if (ui_s->decode_s)
|
||||
{
|
||||
msi_add_output(ui_s->decode_s, NULL, R_SIM_VIDEO);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("jpg decode new msi failed\n");
|
||||
}
|
||||
|
||||
//接收usb的jpg数据,配置需要解码的参数(320x180),然后给到S_JPG_DECODE进行解码,最后给到P0去显示(设置是P0的类型)
|
||||
ui_s->usb_P0_jpg_s = jpg_decode_msg_msi(SR_OTHER_JPG_USB1,320,180,320,180,FSTYPE_USB_CAM0);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (ui_s->usb_P0_jpg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(ui_s->usb_P0_jpg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 0 << 16 | 0);
|
||||
msi_add_output(ui_s->usb_P0_jpg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("jpg decode msg 0 new msi failed\n");
|
||||
}
|
||||
|
||||
//接收usb的jpg数据,配置需要解码的参数(320x180),然后给到S_JPG_DECODE进行解码,最后给到P0去显示(设置是P0的类型)
|
||||
ui_s->usb_P1_jpg_s = jpg_decode_msg_msi(SR_OTHER_JPG_USB2,320,180,320,180,FSTYPE_USB_CAM1);
|
||||
//将other_jpg的数据给到S_JPG_DECODE进行编码
|
||||
if (ui_s->usb_P1_jpg_s)
|
||||
{
|
||||
// 配置解码的坐标值
|
||||
msi_do_cmd(ui_s->usb_P1_jpg_s, MSI_CMD_DECODE_JPEG_MSG, MSI_JPEG_DECODE_X_Y, 360 << 16 | 0);
|
||||
msi_add_output(ui_s->usb_P1_jpg_s, NULL, S_JPG_DECODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("jpg decode msg 1 new msi failed\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_preview_usb_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *preview_usb_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct preview_usb_s *ui_s = (struct preview_usb_s*)STREAM_LIBC_ZALLOC(sizeof(struct preview_usb_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "preview_usb_pip");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_preview_usb_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
183
sdk/app/ui/takephoto_ui.c
Normal file
183
sdk/app/ui/takephoto_ui.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/***************************************************************************************
|
||||
这个主要是预览,通过scale3_msi将dvp/csi数据scale到对应的分辨率作为数据流发送出去
|
||||
然后lcd_msi需要接收对应的数据去显示
|
||||
这里只是产生对应数据流,数据用途实际需要终端流(比如lcd流)接收后去处理
|
||||
|
||||
----> R_VIDEO_P0(320x240)
|
||||
| (lcd_video_p0)
|
||||
S_PREVIEW_SCALE3 -----|
|
||||
(scale3) |
|
||||
----> R_VIDEO_P1(320x240)
|
||||
(lcd_video_p1)
|
||||
***************************************************************************************/
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "stream_frame.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "scale_msi/scale3_normal_msi.h"
|
||||
|
||||
extern void common_takephoto_over_dpi_api(struct msi *scale3, uint16_t normal_w, uint16_t noraml_h, uint16_t thumb_w, uint16_t thumb_h);
|
||||
extern void common_takephoto_noraml_api(struct msi *jpg_normal_msi);
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_indev_t *indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct takephoto_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
uint16_t w, h;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_ui;
|
||||
|
||||
struct msi *s;
|
||||
struct msi *over_dpi_msi;
|
||||
struct msi *thumb_msi;
|
||||
struct msi *scale1_jpg_recode_msi;
|
||||
struct msi *jpg_normal_msi;
|
||||
};
|
||||
|
||||
static void exit_takephoto_ui(lv_event_t *e)
|
||||
{
|
||||
struct takephoto_ui_s *ui_s = (struct takephoto_ui_s *) lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
msi_del_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_del_output(ui_s->s, NULL, R_VIDEO_P1);
|
||||
ui_s->s->enable = 0;
|
||||
// 关闭VIDEO P0,VIDEO P1的使能,释放占住的scale3的fb
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
|
||||
|
||||
if (ui_s->s)
|
||||
{
|
||||
msi_do_cmd(ui_s->s, MSI_CMD_SCALE3_NORMAL, MSI_SCALE3_START, 0);
|
||||
if (ui_s->thumb_msi)
|
||||
{
|
||||
msi_del_output(ui_s->s, NULL, ui_s->thumb_msi->name);
|
||||
msi_put(ui_s->thumb_msi);
|
||||
}
|
||||
if (ui_s->over_dpi_msi)
|
||||
{
|
||||
msi_del_output(ui_s->s, NULL, ui_s->over_dpi_msi->name);
|
||||
msi_put(ui_s->over_dpi_msi);
|
||||
}
|
||||
}
|
||||
|
||||
if (ui_s->scale1_jpg_recode_msi)
|
||||
{
|
||||
msi_put(ui_s->scale1_jpg_recode_msi);
|
||||
}
|
||||
|
||||
if(ui_s->jpg_normal_msi)
|
||||
{
|
||||
msi_put(ui_s->jpg_normal_msi);
|
||||
}
|
||||
msi_destroy(ui_s->s);
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
|
||||
static void takephoto_action(lv_event_t *e)
|
||||
{
|
||||
struct takephoto_ui_s *ui_s = (struct takephoto_ui_s *) lv_event_get_user_data(e);
|
||||
// 没有找到重新编码的msi
|
||||
if (!ui_s->scale1_jpg_recode_msi)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//测试代码,如果是需要插值拍照
|
||||
if (0)
|
||||
{
|
||||
// 设置需要拍照的分辨率,这里是demo,暂时固定,实际需要通过设置文件去配置
|
||||
uint32_t w = 2560;
|
||||
uint32_t h = 1440;
|
||||
uint32_t dpi_w_h = w << 16 | h;
|
||||
msi_do_cmd(ui_s->scale1_jpg_recode_msi, MSI_CMD_SCALE1, MSI_SCALE1_RESET_DPI, dpi_w_h);
|
||||
os_printf("takephoto_action\n");
|
||||
|
||||
// 缩略图320x240
|
||||
// 原图yuv
|
||||
common_takephoto_over_dpi_api(ui_s->s, 0, 0, 320, 240);
|
||||
}
|
||||
//非插值拍照
|
||||
else
|
||||
{
|
||||
if(ui_s->jpg_normal_msi)
|
||||
{
|
||||
common_takephoto_noraml_api(ui_s->jpg_normal_msi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 进入预览的ui,那么就要创建新的ui去显示预览图了
|
||||
static void enter_takephoto_ui(lv_event_t *e)
|
||||
{
|
||||
struct takephoto_ui_s *ui_s = (struct takephoto_ui_s *) lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_add_style(ui, &g_style, 0);
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
// 绑定流到Video_P0,Video_P1显示
|
||||
ui_s->s = scale3_normal_msi2(S_PREVIEW_SCALE3, FSTYPE_YUV_P0, ui_s->w, ui_s->h);
|
||||
if (ui_s->s)
|
||||
{
|
||||
|
||||
msi_do_cmd(ui_s->s, MSI_CMD_SCALE3_NORMAL, MSI_SCALE3_START, 0x01);
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P0);
|
||||
msi_add_output(ui_s->s, NULL, R_VIDEO_P1);
|
||||
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
|
||||
|
||||
ui_s->over_dpi_msi = msi_find(SR_OVER_DPI_JPG, 1);
|
||||
if (ui_s->over_dpi_msi)
|
||||
{
|
||||
msi_add_output(ui_s->s, NULL, ui_s->over_dpi_msi->name);
|
||||
}
|
||||
|
||||
ui_s->thumb_msi = msi_find(SR_OVER_DPI_THUMB_JPG, 1);
|
||||
if (ui_s->thumb_msi)
|
||||
{
|
||||
msi_add_output(ui_s->s, NULL, ui_s->thumb_msi->name);
|
||||
}
|
||||
|
||||
ui_s->jpg_normal_msi = msi_find(R_JPG_THUMB, 1);
|
||||
ui_s->s->enable = 1;
|
||||
}
|
||||
ui_s->scale1_jpg_recode_msi = msi_find(R_SCALE1_JPG_RECODE, 1);
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
lv_obj_add_event_cb(ui, exit_takephoto_ui, LV_EVENT_LONG_PRESSED, ui_s);
|
||||
lv_obj_add_event_cb(ui, takephoto_action, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *takephoto_ui(lv_group_t *group, lv_obj_t *base_ui, uint16_t w, uint16_t h)
|
||||
{
|
||||
struct takephoto_ui_s *ui_s = (struct takephoto_ui_s *) STREAM_LIBC_ZALLOC(sizeof(struct takephoto_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
ui_s->w = w;
|
||||
ui_s->h = h;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "takephoto");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_takephoto_ui, LV_EVENT_SHORT_CLICKED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
111
sdk/app/ui/touch_pad_test_ui.c
Normal file
111
sdk/app/ui/touch_pad_test_ui.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl_ui.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
extern lv_indev_t * indev_keypad;
|
||||
extern lv_style_t g_style;
|
||||
struct touch_pad_test_ui_s
|
||||
{
|
||||
lv_group_t *last_group;
|
||||
lv_obj_t *base_ui;
|
||||
|
||||
lv_group_t *now_group;
|
||||
lv_obj_t *now_label;
|
||||
lv_obj_t *now_label2;
|
||||
lv_obj_t *now_btn;
|
||||
lv_obj_t *now_btn2;
|
||||
lv_obj_t *now_ui;
|
||||
};
|
||||
|
||||
static void btn_event_cb(lv_event_t* e) {
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t* btn = lv_event_get_target(e);
|
||||
if (code == LV_EVENT_CLICKED) {
|
||||
static uint8_t cnt = 0;
|
||||
cnt++;
|
||||
lv_obj_t* label = lv_obj_get_child(btn, 0);
|
||||
lv_label_set_text_fmt(label, "Button: %d", cnt);
|
||||
}
|
||||
}
|
||||
|
||||
static void exit_touch_pad_test_ui(lv_event_t* e) {
|
||||
struct touch_pad_test_ui_s *ui_s = (struct touch_pad_test_ui_s *)lv_event_get_user_data(e);
|
||||
lv_indev_set_group(indev_keypad, ui_s->last_group);
|
||||
lv_obj_clear_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_del(ui_s->now_label);
|
||||
lv_obj_del(ui_s->now_btn);
|
||||
lv_obj_del(ui_s->now_label2);
|
||||
lv_obj_del(ui_s->now_btn2);
|
||||
lv_group_del(ui_s->now_group);
|
||||
ui_s->now_group = NULL;
|
||||
ui_s->now_label = NULL;
|
||||
ui_s->now_btn = NULL;
|
||||
ui_s->now_label2 = NULL;
|
||||
ui_s->now_btn2 = NULL;
|
||||
|
||||
lv_obj_del(ui_s->now_ui);
|
||||
}
|
||||
|
||||
static void enter_touch_pad_test_ui(lv_event_t* e) {
|
||||
|
||||
struct touch_pad_test_ui_s *ui_s = (struct touch_pad_test_ui_s *)lv_event_get_user_data(e);
|
||||
lv_obj_add_flag(ui_s->base_ui, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_t *ui = lv_obj_create(lv_scr_act());
|
||||
ui_s->now_ui = ui;
|
||||
lv_obj_set_size(ui, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
lv_obj_t* btn = lv_btn_create(ui);
|
||||
lv_obj_set_size(btn, 150, 50);
|
||||
lv_obj_center(btn);
|
||||
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);
|
||||
ui_s->now_btn = btn;
|
||||
|
||||
lv_obj_t* btn2 = lv_btn_create(ui);
|
||||
lv_obj_set_size(btn2, 50, 50);
|
||||
lv_obj_center(btn2);
|
||||
lv_obj_align(btn2, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
lv_obj_add_event_cb(btn2, exit_touch_pad_test_ui, LV_EVENT_PRESSED, ui_s);
|
||||
ui_s->now_btn2 = btn2;
|
||||
|
||||
lv_obj_t* label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Button");
|
||||
lv_obj_center(label);
|
||||
ui_s->now_label = label;
|
||||
|
||||
lv_obj_t* label2 = lv_label_create(btn2);
|
||||
lv_label_set_text(label2, LV_SYMBOL_CLOSE);
|
||||
lv_obj_center(label2);
|
||||
ui_s->now_label2 = label2;
|
||||
|
||||
lv_group_t *group;
|
||||
group = lv_group_create();
|
||||
lv_indev_set_group(indev_keypad, group);
|
||||
|
||||
lv_group_add_obj(group, ui);
|
||||
ui_s->now_group = group;
|
||||
|
||||
// lv_obj_add_event_cb(ui, exit_touch_pad_test_ui, LV_EVENT_PRESSED, ui_s);
|
||||
}
|
||||
|
||||
lv_obj_t *touch_pad_test_ui(lv_group_t *group,lv_obj_t *base_ui)
|
||||
{
|
||||
struct touch_pad_test_ui_s *ui_s = (struct touch_pad_test_ui_s*)STREAM_LIBC_ZALLOC(sizeof(struct touch_pad_test_ui_s));
|
||||
ui_s->last_group = group;
|
||||
ui_s->base_ui = base_ui;
|
||||
lv_obj_t *btn = lv_list_add_btn(base_ui, NULL, "touch_pad_test");
|
||||
lv_group_add_obj(group, btn);
|
||||
lv_obj_add_event_cb(btn, enter_touch_pad_test_ui, LV_EVENT_PRESSED, ui_s);
|
||||
return btn;
|
||||
}
|
||||
Reference in New Issue
Block a user