视频 (Video)

视频控件是用于显示和播放视频的控件。该控件支持多种视频格式,多种数据源(内存、文件系统、FTL 存储),并提供了丰富的播放控制接口。

用法

视频格式

视频控件支持的视频资源格式有 MJPEG, AVI, H264,各格式特性如下:

不同视频格式对比

类型

资源大小

支持音频

支持透明

解码时资源消耗

支持跳帧

帧编码

解码器

MJPEG

较小

✔️

JPEG

HW(RTL8773G)/SW

AVI

稍大于 MJPEG

✔️

✔️

JPEG

HW(RTL8773G)/SW

H264

极小

较大

H264

SW

  1. 视频文件资源大小

视频文件的大小受到视频时长、视频帧率、视频分辨率、画面复杂度、是否带音频等多种因素影响。当画面高频内容多,即变化多纹理多时,画面复杂度越高,通常导出视频体积相应越大。 视频文件转换时,可设定合适的质量参数以平衡空间和画质需求。导出的 AVI 格式视频支持 PC 平台常用播放器预览。

  1. 视频资源转换

使用转换工具生成 HoneyGUI 可识别接收的视频格式:

  1. 转换工具支持导入常见的视频格式,支持导入图片序列

  2. 不同导出格式的相同质量参数不相对等

详细的视频资源转换制作,详见转换工具说明文档。

访问方式

视频控件支持多种资源访问方式:

  • 直接映射:直接从内存地址读取,如 RAM/PSRAM,NOR Flash XIP。

  • 文件系统:通过文件系统接口读取,如 LittleFS。

  • 缓冲访问:通过存储地址缓冲读取,如 NAND Flash。

视频控件创建时,需根据资源的访问方式调用不同的创建 API

视频控件创建接口

类型

创建函数

直接映射

gui_video_create_from_mem()

文件系统

gui_video_create_from_fs()

缓冲访问

gui_video_create_from_ftl()

播放控制

播放状态

使用函数 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_
    unsigned char *resource_root = (unsigned char *)_binary_earth_420_410_502_40_lq_mjpg_start;
#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

Defines

GUI_VIDEO_REPEAT_INFINITE 0xFFFFFFFF
IMG_LIVE_FPS (25)

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
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
enum GUI_VIDEO_RES

Values:

enumerator GUI_IMG_LIVE_SUCCESSED
enum VIDEO_MJPEG_SCAN_STATE

Values:

enumerator MJPEG_SCAN_INIT
enumerator MJPEG_SCAN_START
enumerator MJPEG_SCAN_END
enumerator MJPEG_SCAN_EOF
enum GUI_VIDEO_TYPE

Values:

enumerator VIDEO_TYPE_NULL
enumerator VIDEO_TYPE_MJPEG
enumerator VIDEO_TYPE_H264
enumerator VIDEO_TYPE_AVI
enum AVI_CHUNK_TYPE

Values:

enumerator CHUNK_VIDEO
enumerator CHUNK_AUDIO
enumerator CHUNK_UNKNOWN

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.

备注

  1. For file paths, please use the file system (FS) API to get the file size.

  2. 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)
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

Public Members

char symbol[4]
uint32_t w
uint32_t h
uint32_t frame_num
uint32_t frame_time
uint32_t size
struct gui_riff_header_t

Public Members

char symbol[4]
uint32_t size
char format[4]
struct MainAVIHeader_t

Public Members

uint32_t usec_per_frame
uint32_t max_byte_rate
uint32_t reserved_0
uint32_t flags
uint32_t total_frame
uint32_t initial_frame
uint32_t streams
uint32_t buffer_size
uint32_t width
uint32_t height
struct AVIStreamHeader_t

Public Members

char type[4]
uint32_t handler
uint32_t flags
uint32_t priority
uint32_t initial_frames
uint32_t scale
uint32_t rate
uint32_t start
uint32_t length
uint32_t buffer_size
uint32_t quality
uint32_t sample_size
uint16_t frame[4]
uint32_t stream_format
uint32_t length_format
struct BitMapInfoHeader_t

Public Members

uint32_t size
uint32_t width
uint32_t height
uint16_t planes
uint16_t bit_count
uint32_t compression
uint32_t image_size
uint32_t x_pels_per_meter
uint32_t y_pels_per_meter
uint32_t colors_used
uint32_t colors_important
struct WaveFormateX_t

Public Members

uint16_t format_tag
uint16_t channels
uint32_t samples_per_sec
uint32_t ave_bytes_per_sec
uint16_t block_align
uint16_t bits_per_sample
uint16_t size_extra
struct IndexList_t

Public Members

uint32_t indexID
uint32_t index_size
struct IndexItem_t

Public Members

uint32_t chunk_ID
uint32_t flags
uint32_t offset
uint32_t size
struct AviMoviChunk_t

Public Members

uint32_t offset
uint32_t len
uint32_t type
struct gui_video_t

stb img widget information structure

Public Members

gui_obj_t base
gui_img_t *img
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