视频特效滤镜 via FFmpeg Filter

编程入门 行业动态 更新时间:2024-10-26 18:23:44

视频特效<a href=https://www.elefans.com/category/jswz/34/1771381.html style=滤镜 via FFmpeg Filter"/>

视频特效滤镜 via FFmpeg Filter

视频特效滤镜 via FFmpeg Filter

  • 视频特效定义
  • FFmpeg filter
    • av_filter_base 类
      • av_filter_base::video_filter_init_begin 函数
      • Video_filter 子类
      • av_filter_base::filter_init_end 函数
      • av_filter_base::do_filter 函数
  • 其他框架的滤镜

视频特效定义

视频特效(Video effects 或 Visual effects)是对每帧图像进行各种数字化处理达到的效果。如对画面的尺寸、位置、亮度及色度等参数进行处理,就可获得缩放、旋转、黑白、油画等各种效果。

常见的特效技术有:缩放、旋转、裁剪、叠加、老电影、黑白、淡入淡出、水印、去噪、慢动作、2D 转 3D 等等。

FFmpeg filter

关于 FFmpeg filter 的架构,请参考我的另一篇文章 音频特效插件 via FFmpeg。

av_filter_base 类

用 FFmpeg 的 filter 开发时主要区别就是把不同的 filter description string 传到 filtergraph 中,然后设定 sink 端 prefer 的参数,其他部分几乎是一样的,所以我把 filter 的使用封装成了一个 av_filter_base 类,代码请参考 这里。

av_filter_base::video_filter_init_begin 函数

创建 video source 和 sink filter。

int video_filter_init_begin(AVCodecContext *dec_ctx, AVRational stream_time_base)
{int hr = -1;m_filter_graph = avfilter_graph_alloc();RETURN_IF_NULL(m_filter_graph);char args[512] = {0};_snprintf_s(args, sizeof(args),"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,stream_time_base.num, stream_time_base.den,dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);/* buffer video source: the decoded frames from the decoder will be inserted here. */const AVFilter *buffersrc = avfilter_get_by_name("buffer");hr = avfilter_graph_create_filter(&m_buffersrc_ctx, buffersrc, "in", args, NULL, m_filter_graph);RETURN_IF_FAILED(hr);/* buffer video sink: to terminate the filter chain. */const AVFilter *buffersink = avfilter_get_by_name("buffersink");hr = avfilter_graph_create_filter(&m_buffersink_ctx, buffersink, "out", NULL, NULL, m_filter_graph);RETURN_IF_FAILED(hr);return hr;
}

Video_filter 子类

init_opts 函数需要子类去重写,下面的例子设定了 sink filter 支持的视频格式。

class Video_filter : public av_filter_base
{
public:Video_filter(): m_enc_ctx(NULL){ }int init( AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVRational stream_time_base, const char *filters_descr ){m_enc_ctx = enc_ctx;return av_filter_base::init(dec_ctx, stream_time_base, filters_descr);}protected:virtual int init_opts(){RETURN_IF_NULL(m_enc_ctx);return av_opt_set_bin( m_buffersink_ctx, "pix_fmts", (uint8_t*)&m_enc_ctx->pix_fmt,sizeof(m_enc_ctx->pix_fmt), AV_OPT_SEARCH_CHILDREN );}
private:AVCodecContext* m_enc_ctx;
};

av_filter_base::filter_init_end 函数

请看 这里,一模一样。

av_filter_base::do_filter 函数

这里重载了两个 do_filter 函数,一个是通过回调函数处理每一帧,代码请看 这里;另一个是返回帧集合,代码如下:

int do_filter(AVFrame* in_frame, std::queue<AVFrame*>& out_frames)
{RETURN_IF_NULL(in_frame);int hr = -1;in_frame->pts = in_frame->best_effort_timestamp;/* push the decoded frame into the filtergraph */hr = av_buffersrc_add_frame_flags(m_buffersrc_ctx, in_frame, AV_BUFFERSRC_FLAG_KEEP_REF);RETURN_IF_FAILED(hr);/* pull filtered frames from the filtergraph */AVFrame* filt_frame = NULL;while (true) {filt_frame = av_frame_alloc();RETURN_IF_NULL(filt_frame);hr = av_buffersink_get_frame(m_buffersink_ctx, filt_frame);if (hr == AVERROR(EAGAIN) || hr == AVERROR_EOF)break;GOTO_IF_FAILED(hr);out_frames.push(filt_frame);filt_frame = NULL;}
}

其他框架的滤镜

  • 关于 DirectShow 的视频滤镜请参考 这里。
  • 关于 Media Foundation 的视频滤镜请参考 这里。


EOF

更多推荐

视频特效滤镜 via FFmpeg Filter

本文发布于:2024-02-17 17:26:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1694837.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:滤镜   特效   视频   Filter   FFmpeg

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!