视频 (Video)
视频控件是用于显示和播放视频的控件。该控件支持多种视频格式,多种数据源(内存、文件系统、FTL 存储),并提供了丰富的播放控制接口。
用法
视频格式
视频控件支持的视频资源格式有 MJPEG, AVI, H264,各格式特性如下:
类型 |
资源大小 |
支持音频 |
支持透明 |
解码时资源消耗 |
支持跳帧 |
帧编码 |
解码器 |
|---|---|---|---|---|---|---|---|
MJPEG |
较小 |
❌ |
❌ |
小 |
✔️ |
JPEG |
HW(RTL8773G)/SW |
AVI |
稍大于 MJPEG |
✔️ |
❌ |
小 |
✔️ |
JPEG |
HW(RTL8773G)/SW |
H264 |
极小 |
❌ |
❌ |
较大 |
❌ |
H264 |
SW |
视频文件资源大小
视频文件的大小受到视频时长、视频帧率、视频分辨率、画面复杂度、是否带音频等多种因素影响。当画面高频内容多,即变化多纹理多时,画面复杂度越高,通常导出视频体积相应越大。 视频文件转换时,可设定合适的质量参数以平衡空间和画质需求。导出的 AVI 格式视频支持 PC 平台常用播放器预览。
视频资源转换
使用转换工具生成 HoneyGUI 可识别接收的视频格式:
转换工具支持导入常见的视频格式,支持导入图片序列
不同导出格式的相同质量参数不相对等
详细的视频资源转换制作,详见转换工具说明文档。
访问方式
视频控件支持多种资源访问方式:
视频控件创建时,需根据资源的访问方式调用不同的创建 API。
类型 |
创建函数 |
|---|---|
直接映射 |
|
文件系统 |
|
缓冲访问 |
播放控制
播放状态
使用函数 gui_video_set_state() 来设置视频播放状态,支持设置的状态有播放( GUI_VIDEO_STATE_PLAYING)、
暂停( GUI_VIDEO_STATE_PAUSE)、停止( GUI_VIDEO_STATE_STOP)。
在视频控件处于停止状态( GUI_VIDEO_STATE_STOP)时设置播放( GUI_VIDEO_STATE_PLAYING)视频,视频将从第一帧开始重播。
重复播放
使用函数 gui_video_set_repeat_count() 来设置视频的重复播放次数,设置重复次数为 1 时,视频将播放 2 次。
通过设置重复次数为 GUI_VIDEO_REPEAT_INFINITE 或负数使视频无限循环播放。
帧率设置
视频控件使用资源文件中的帧率作为初始播放帧率,MJPEG 文件中不包含帧率信息,使用默认 25 fps,AVI 和 H264 中均包含有帧率信息。
使用函数 gui_video_set_frame_rate() 来设置视频的播放帧率,将会覆盖视频原有的帧率设置。
使用函数 gui_video_get_frame_time() 来获取实际设置的帧播放间隔时间。
步进设置
对支持跳帧播放的视频格式,使用函数 gui_video_set_frame_step() 设置视频帧的播放步进,以实现快进的播放效果,不支持倒放。
使用函数 gui_video_get_frame_step() 来获取当前视频控件的播放步进。
UI 变换
缩放
使用函数 gui_video_set_scale() 来设置视频画面的缩放参数,
调节视频画面比例。
示例
以下代码段示例了如何创建视频控件,设置播放帧率,控制播放,以及如何注册交互事件,并设置播放速度。
static void video_click_cb(void *obj)
{
gui_video_t *this = (gui_video_t *)obj;
GUI_VIDEO_STATE state = gui_video_get_state(this);
if (state == GUI_VIDEO_STATE_PLAYING)
{
gui_video_set_state(this, GUI_VIDEO_STATE_PAUSE);
}
else
{
gui_video_set_state(this, GUI_VIDEO_STATE_PLAYING);
}
}
static void video_pressing_cb(void *obj)
{
gui_video_t *this = (gui_video_t *)obj;
static uint32_t cnt = 0;
uint32_t frame_time = gui_video_get_frame_time(this);
if (frame_time > 30)
{
cnt = 0;
gui_video_set_frame_rate(this, 50.f);
}
else if (frame_time > 15)
{
cnt++;
if (cnt >= 80)
{
cnt = 80;
gui_video_set_frame_step(this, 2);
}
}
}
static void video_release_cb(void *obj)
{
gui_video_t *this = (gui_video_t *)obj;
gui_video_set_frame_rate(this, 30.f);
gui_video_set_frame_step(this, 1);
}
static int app_init(void)
{
#ifdef _HONEYGUI_SIMULATOR_
resource_root = load_resource_file(
"/pc/example/widget/video/root_image/earth_420_410_502_40_lq.mjpg");
if (resource_root == NULL)
{
return -1;
}
#else
unsigned char *resource_root = (unsigned char *)EARTH_420_410_502_40_LQ_MJPG;
#endif
gui_log("GUI Video Widget Example Start\n");
gui_video_t *video = gui_video_create_from_mem(gui_obj_get_root(), "earth",
(void *)resource_root,
0, 0, 410,
502);
/* Set default frame rate to 30 FPS */
gui_video_set_frame_rate(video, 30.f);
gui_video_set_state(video, GUI_VIDEO_STATE_PLAYING); // Set initial state to Playing
gui_video_set_repeat_count(video, GUI_VIDEO_REPEAT_INFINITE); // Enable infinite loop
/*
* Register CLICK event callback.
* Logic: Toggle between Play and Pause states.
*/
gui_obj_add_event_cb(video,
(gui_event_cb_t)video_click_cb,
GUI_EVENT_TOUCH_CLICKED,
NULL);
/*
* Register PRESSING (Long Press) event callback.
* Logic: Handle 2-stage Fast Forward:
* 1. Initial long press: Increase frame rate (FPS) for smooth fast forward.
* 2. Extended long press: Increase seek step for faster fast forward.
*/
gui_obj_add_event_cb(video,
(gui_event_cb_t)video_pressing_cb,
GUI_EVENT_TOUCH_PRESSING,
NULL);
/*
* Register RELEASE event callback.
* Logic: Restore initial playback settings (Default FPS and Step) when finger is lifted.
*/
gui_obj_add_event_cb(video,
(gui_event_cb_t)video_release_cb,
GUI_EVENT_TOUCH_RELEASED,
NULL);
return 0;
}
GUI_INIT_APP_EXPORT(app_init);

API
Enums
-
enum GUI_VIDEO_EVENT
Values:
-
enumerator GUI_VIDEO_EVENT_FRAME_UPDATE
-
enumerator GUI_VIDEO_EVENT_PLAY
-
enumerator GUI_VIDEO_EVENT_PAUSE
-
enumerator GUI_VIDEO_EVENT_STOP
-
enumerator GUI_VIDEO_EVENT_END
-
enumerator GUI_VIDEO_EVENT_FRAME_UPDATE
-
enum GUI_VIDEO_STATE
Values:
-
enumerator GUI_VIDEO_STATE_ERR
-
enumerator GUI_VIDEO_STATE_INIT
-
enumerator GUI_VIDEO_STATE_PLAYING
-
enumerator GUI_VIDEO_STATE_PAUSE
-
enumerator GUI_VIDEO_STATE_STOP
-
enumerator GUI_VIDEO_STATE_ERR
-
enum VIDEO_MJPEG_SCAN_STATE
Values:
-
enumerator MJPEG_SCAN_INIT
-
enumerator MJPEG_SCAN_START
-
enumerator MJPEG_SCAN_END
-
enumerator MJPEG_SCAN_EOF
-
enumerator MJPEG_SCAN_INIT
Functions
-
int gui_video_get_filesize_from_addr(void *addr, uint8_t storage_type)
Retrieves the video file size from a memory address or FTL storage address.
备注
For file paths, please use the file system (FS) API to get the file size.
Supported video formats: mjpeg, avi, h264.
- 参数:
addr -- [in] The starting address of the video data.
For IMG_SRC_MEMADDR: Pointer to the data in RAM or Flash.
For IMG_SRC_FTL: Storage address or offset in Flash.
storage_type -- [in] The storage source type. Supported types: IMG_SRC_MEMADDR, IMG_SRC_FTL.
- 返回:
int Returns the file size in bytes. Returns 0 or a negative value on failure.
-
void gui_video_set_frame_rate(gui_video_t *this, float fps)
-
uint32_t gui_video_get_frame_time(gui_video_t *this)
-
void gui_video_set_scale(gui_video_t *this, float scale_x, float scale_y)
-
void gui_video_set_state(gui_video_t *this, GUI_VIDEO_STATE state)
Set the playback state of a video widget.
备注
When set state Play at state Stop, widget will play from the beginning.
- 参数:
this -- Pointer to the video widget (must be valid).
state -- Target state, as defined by GUI_VIDEO_STATE (e.g., Play, Pause, Stop).
-
void gui_video_set_repeat_count(gui_video_t *this, int32_t cnt)
Set the repeat (loop) count for video playback.
- 参数:
this -- Pointer to the video widget (must be valid).
cnt -- Number of times to repeat playback after the first run:
cnt > 0: Play the video cnt additional times (total plays = 1 + cnt).
cnt = 0: Do not repeat (play once).
GUI_VIDEO_REPEAT_INFINITE: Repeat indefinitely (infinite loop).
-
GUI_VIDEO_STATE gui_video_get_state(gui_video_t *this)
-
void gui_video_set_frame_step(gui_video_t *this, uint32_t step)
-
uint32_t gui_video_get_frame_step(gui_video_t *this)
-
void gui_video_refresh_size(gui_video_t *this)
-
void gui_video_refresh_type(gui_video_t *this)
-
void gui_video_set_src(gui_video_t *this, void *src, uint8_t storage_type)
Switch the video source at runtime.
Both the container type and the storage location may change: any MJPEG / H264 / AVI source in memory, in FTL, or in the filesystem can replace any other. The new container is parsed, the widget geometry and frame period are taken from it, and playback restarts from the first frame.
All resources held for the previous source are released — the decoded frame buffer (returned to the allocator that produced it), the H264 decoder, and the frame index array. Nothing is reallocated in place.
On any failure the widget keeps playing its current source unchanged.
备注
The widget does not copy
src. For IMG_SRC_FILESYS the path string must stay valid for as long as the source is in use, since it is reopened on every frame.备注
Call from the GUI thread (event callback or server hook) so the swap cannot interleave with a draw pass.
备注
Playback state is forced to GUI_VIDEO_STATE_PLAYING; the repeat count set through gui_video_set_repeat_count() is kept.
- 参数:
this -- Widget pointer (must not be NULL).
src -- New source: pointer to the data in RAM/Flash for IMG_SRC_MEMADDR, base address for IMG_SRC_FTL, or a NUL-terminated VFS path for IMG_SRC_FILESYS.
storage_type -- IMG_SRC_MEMADDR, IMG_SRC_FTL, or IMG_SRC_FILESYS.
-
gui_video_t *gui_video_create_from_ftl(void *parent, const char *name, void *addr, int16_t x, int16_t y, int16_t w, int16_t h)
Create a video widget from an FTL source(cannot be accessed directly) and attach it to a parent container.
- 参数:
parent -- Pointer to the parent GUI object (must be valid).
name -- Widget name/identifier.
addr -- Pointer to the FTL source handle or buffer.
x -- Top-left x position relative to the parent.
y -- Top-left y position relative to the parent.
w -- Width in pixels (will be overwritten by the video file).
h -- Height in pixels (will be overwritten by the video file).
- 返回:
Pointer to gui_video_t on success; NULL on failure.
-
gui_video_t *gui_video_create_from_fs(void *parent, const char *name, void *addr, int16_t x, int16_t y, int16_t w, int16_t h)
Create a video widget from a file system and attach it to a parent container.
- 参数:
parent -- Pointer to the parent GUI object (must be valid).
name -- Widget name/identifier.
addr -- Pointer to the file path string.
x -- Top-left x position relative to the parent.
y -- Top-left y position relative to the parent.
w -- Width in pixels (will be overwritten by video file).
h -- Height in pixels (will be overwritten by video file).
- 返回:
Pointer to gui_video_t on success; NULL on failure.
-
gui_video_t *gui_video_create_from_mem(void *parent, const char *name, void *addr, int16_t x, int16_t y, int16_t w, int16_t h)
Create a video widget from a memory buffer and attach it to a parent container.
- 参数:
parent -- Pointer to the parent GUI object (must be valid).
name -- Widget name/identifier.
addr -- Pointer to the memory buffer containing video data.
x -- Top-left x position relative to the parent.
y -- Top-left y position relative to the parent.
w -- Width in pixels (will be overwritten by video file).
h -- Height in pixels (will be overwritten by video file).
- 返回:
Pointer to gui_video_t on success; NULL on failure.
-
struct gui_h264_header_t
-
struct gui_riff_header_t
-
struct MainAVIHeader_t
-
struct AVIStreamHeader_t
-
struct BitMapInfoHeader_t
-
struct WaveFormateX_t
-
struct IndexList_t
-
struct IndexItem_t
-
struct AviMoviChunk_t
-
struct gui_video_t
stb img widget information structure
Public Members
-
gui_obj_t base
-
void *data
-
uint32_t num_frame
-
uint8_t **array
-
gui_rgb_data_head_t header
-
uint8_t *frame_buff
-
uint8_t *frame_buff_raw
-
void *decoder
-
uint32_t frame_time
-
uint32_t frame_step
-
int32_t frame_cur
-
int32_t frame_last
-
int32_t repeat_cnt
-
uint8_t img_type
-
uint8_t storage_type
-
uint8_t state
-
uint32_t frame_chunk_cur
-
uint32_t chunk_num
-
uint8_t rgb_type
-
gui_obj_t base