FFplay视频滤镜分析

Posted Loken2020

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FFplay视频滤镜分析相关的知识,希望对你有一定的参考价值。

FFplay 播放器的命令行是可以指定多个视频滤镜,然后按 w 键切换查看效果的,命令如下:

# linux 命令
ffplay.exe -x 400 \\
-vf "drawtext=fontsize=200:fontfile=FreeSerif.ttf:text='FFmpeg':x=150:y=100" \\
-vf "drawtext=fontsize=200:fontfile=FreeSerif.ttf:text='Principle':x=150:y=100" \\
-i juren.mp4
# windows 命令
ffplay.exe -x 400 ^
-vf "drawtext=fontsize=200:fontfile=FreeSerif.ttf:text='FFmpeg':x=150:y=100" ^
-vf "drawtext=fontsize=200:fontfile=FreeSerif.ttf:text='Principle':x=150:y=100" ^
-i juren.mp4

扩展知识:Linux 里面连接两行命令用的是 \\ 斜杠符号,而 Windows 系统连接两行命令用的是 ^ 平方符号。

FreeSerif.ttf 是字体文件,如果没有这个字体文件,请网上下载保存到跟 ffplay.exe 同样的目录

上面的命令定义了两个视频滤镜,这两个滤镜都是往视频加一个文字水印,那是不是两个滤镜都会生效呢?

不是,只会默认第一个滤镜生效,但是你可以按 w 键切换到第二个滤镜,效果如下:


下面来讲一下 ffpaly.c 里面是怎么解析 -vf 参数的,如下:

可以看到,是调的 opt_add_vfilter() 来处理 -vf 命令行参数的。

opt_add_vfilter() 函数的代码如下:

static const char **vfilters_list = NULL;
static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)

    GROW_ARRAY(vfilters_list, nb_vfilters);
    vfilters_list[nb_vfilters - 1] = arg;
    return 0;

vfilters_list 是一个二级指针,GROW_ARRAY() 是 ffmpeg 封装的函数,可以动态扩容。


我们再来看一下处理 w 键事件的逻辑,如下:

w 键的逻辑是,切换到下一个视频滤镜,如果没有下一个视频滤镜了,就切换到音频波形图。

当 cur_stream->vfilter_idx 产生变化的时候,就会触发重新配置视频滤镜的逻辑,如下:

上图的 is->vfilter_idx 其实就是 cur_stream->vfilter_idxffplay 有些函数会把 is 这个名称换成 cur_stream,实际上他们是同一个指针。


configure_video_filters() 函数比较简单,所以只讲一个重点,就是它里面有一个 ffmpeg 像素格式到 SDL 像素格式的映射过程,这个如果你的项目也用到,可以抄过去这个表。

static const struct TextureFormatEntry 
    enum AVPixelFormat format;
    int texture_fmt;
 sdl_texture_format_map[] = 
     AV_PIX_FMT_RGB8,           SDL_PIXELFORMAT_RGB332 ,
     AV_PIX_FMT_RGB444,         SDL_PIXELFORMAT_RGB444 ,
     AV_PIX_FMT_RGB555,         SDL_PIXELFORMAT_RGB555 ,
     AV_PIX_FMT_BGR555,         SDL_PIXELFORMAT_BGR555 ,
     AV_PIX_FMT_RGB565,         SDL_PIXELFORMAT_RGB565 ,
     AV_PIX_FMT_BGR565,         SDL_PIXELFORMAT_BGR565 ,
     AV_PIX_FMT_RGB24,          SDL_PIXELFORMAT_RGB24 ,
     AV_PIX_FMT_BGR24,          SDL_PIXELFORMAT_BGR24 ,
     AV_PIX_FMT_0RGB32,         SDL_PIXELFORMAT_RGB888 ,
     AV_PIX_FMT_0BGR32,         SDL_PIXELFORMAT_BGR888 ,
     AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 ,
     AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 ,
     AV_PIX_FMT_RGB32,          SDL_PIXELFORMAT_ARGB8888 ,
     AV_PIX_FMT_RGB32_1,        SDL_PIXELFORMAT_RGBA8888 ,
     AV_PIX_FMT_BGR32,          SDL_PIXELFORMAT_ABGR8888 ,
     AV_PIX_FMT_BGR32_1,        SDL_PIXELFORMAT_BGRA8888 ,
     AV_PIX_FMT_YUV420P,        SDL_PIXELFORMAT_IYUV ,
     AV_PIX_FMT_YUYV422,        SDL_PIXELFORMAT_YUY2 ,
     AV_PIX_FMT_UYVY422,        SDL_PIXELFORMAT_UYVY ,
     AV_PIX_FMT_NONE,           SDL_PIXELFORMAT_UNKNOWN ,
;

configure_video_filters() 函数最后会配置 is->in_video_filter 跟 is->out_video_filter,就是入口滤镜跟出口滤镜,只需要把解码出来的视频帧往 in_video_filter 丢,然后再从 out_video_filter 读就行了。

更多滤镜函数的用法,请阅读 《FFmpeg实战之路》 一章。


推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:

Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

以上是关于FFplay视频滤镜分析的主要内容,如果未能解决你的问题,请参考以下文章

FFmpeg之ffplay源码简要分析

FFmpeg之ffplay源码简要分析

FFMPEG - ffplay源代码分析

音视频学习之ffplay基础命令整理

ffplay源码分析6-音频重采样

ffmpeg使用说明:ffmpeg/ffplay/ffprobe