lvgl8.3有ffmpeg支持
c
typedef struct {
lv_img_t img;
lv_timer_t * timer;
lv_img_dsc_t imgdsc;
bool auto_restart;
struct ffmpeg_context_s * ffmpeg_ctx;
} lv_ffmpeg_player_t;
typedef enum {
LV_FFMPEG_PLAYER_CMD_START,
LV_FFMPEG_PLAYER_CMD_STOP,
LV_FFMPEG_PLAYER_CMD_PAUSE,
LV_FFMPEG_PLAYER_CMD_RESUME,
_LV_FFMPEG_PLAYER_CMD_LAST
} lv_ffmpeg_player_cmd_t;
struct ffmpeg_context_s {
AVFormatContext * fmt_ctx;
AVCodecContext * video_dec_ctx;
AVStream * video_stream;
uint8_t * video_src_data[4];
uint8_t * video_dst_data[4];
struct SwsContext * sws_ctx;
AVFrame * frame;
AVPacket pkt;
int video_stream_idx;
int video_src_linesize[4];
int video_dst_linesize[4];
enum AVPixelFormat video_dst_pix_fmt;
bool has_alpha;
};
1. lv_ffmpeg_player_create
调用构造函数创建播放器
c
//构造函数
lv_ffmpeg_player_constructor
{
// 主要创建用于刷新图像的定时器
player->timer = lv_timer_create(lv_ffmpeg_player_frame_update_cb,
FRAME_DEF_REFR_PERIOD, obj);
}
2.lv_ffmpeg_player_set_src(player, "/userdata/lvgl_app/birds.mp4");
2.1 打开给定视频文件
c
//打开文件, 寻找视频流及对应解码器 设置最终像素格式等参数
player->ffmpeg_ctx = ffmpeg_open_file(path);
//根据获得的视频流信息申请图像空间及ffmpeg需要的frame pkt
if(ffmpeg_image_allocate(player->ffmpeg_ctx) < 0)
//将ffmpeg解码数据与lvgl图片刷新区域相关联
player->imgdsc.data = ffmpeg_get_img_data(player->ffmpeg_ctx);
lv_img_set_src(&player->img.obj, &(player->imgdsc));
3. lv_ffmpeg_player_set_cmd(player, LV_FFMPEG_PLAYER_CMD_START);
开始播放
c
//重新启动图像刷新定时器
lv_timer_resume(timer);
构造函数中创建
// 主要创建用于刷新图像的定时器
player->timer = lv_timer_create(lv_ffmpeg_player_frame_update_cb,
FRAME_DEF_REFR_PERIOD, obj);
4.简单修改,实现播放rtsp流
c
lv_obj_t * player = lv_ffmpeg_player_create(lv_scr_act());
//lv_ffmpeg_player_set_src(player, "/userdata/lvgl_app/birds.mp4");
lv_ffmpeg_player_set_src(player, "rtsp://admin:p@ssw0rd@192.168.51.210/h264/ch33/main/av_stream");
//lv_ffmpeg_player_set_auto_restart(player, true);
lv_ffmpeg_player_set_cmd(player, LV_FFMPEG_PLAYER_CMD_START);
lv_obj_center(player);
4.1 关闭所有暂停及seek操作
cpp
av_seek_frame(player->ffmpeg_ctx->fmt_ctx,
0, 0, AVSEEK_FLAG_BACKWARD);
lv_timer_pause(player->timer);
4.1 网络初始化
cpp
avformat_network_init();
4.2 设置帧率
cpp
lv_res_t lv_ffmpeg_player_set_src(lv_obj_t * obj, const char * path)
{
if(period > 0) {
LV_LOG_INFO("frame refresh period = %d ms, rate = %d fps",
period, 1000 / period);
lv_timer_set_period(player->timer, period);
}
else {
LV_LOG_WARN("unable to get frame refresh period");
#if rtsp
lv_timer_set_period(player->timer, (1/25)*1000);
#endif
}
}
4.3 设置参数
c
struct ffmpeg_context_s * ffmpeg_open_file(const char * path){
//3.设置打开媒体文件的相关参数
AVDictionary *options = NULL;
av_dict_set(&options, "buffer_size", "6M", 0); // 设置 buffer_size 为 2MB
//以tcp方式打开,如果以udp方式打开将tcp替换为udp
av_dict_set(&options, "rtsp_transport", "tcp", 0);
//设置超时断开连接时间,单位微秒,3000000表示3秒
av_dict_set(&options, "stimeout", "1000000", 0);
//设置最大时延,单位微秒,1000000表示1秒
av_dict_set(&options, "max_delay", "1000000", 0);
//自动开启线程数
av_dict_set(&options, "threads", "auto", 0);
// 设置分析持续时间
//av_dict_set(&options, "analyzeduration", "1000000", 0);
// 设置探测大小
av_dict_set(&options, "probesize", "5000000", 0);
if(avformat_open_input(&(ffmpeg_ctx->fmt_ctx), path, NULL, &options) < 0) {
LV_LOG_ERROR("Could not open source file %s", path);
goto failed;
}
//修改解码帧颜色格式
ffmpeg_ctx->video_dst_pix_fmt = AV_PIX_FMT_RGBA ;
}