滤镜 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
发布评论