日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FFMPEG视频滤镜(一)

發布時間:2024/3/24 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FFMPEG视频滤镜(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

介紹FFmpeg中旋轉rotate、拼接hstack、翻轉hflip、邊緣edgedetect視頻濾鏡的使用方法。

1、 旋轉濾鏡

1.1 名稱:rotate
1.2 語法:-angle:旋轉角度,-ow:輸出圖像寬度,-oh:輸出圖像高度;如:"angle=0.5*PI:ow=1920:oh=1080"
1.3 其他:若需要實時旋轉圖像,則需要動態創建和銷毀濾鏡。
1.4 示例代碼

static int initFilter(AVCodecContext * codecContext0, AVCodecContext * codecContext1, double angle) {int ret = 0;const AVFilter *bufSrc = NULL;const AVFilter *rotate = NULL;const AVFilter *bufSink = NULL;AVFilterInOut *input = NULL;AVFilterInOut *output = NULL;char args[128] = {0};if(NULL == filterGraph)filterGraph = avfilter_graph_alloc();else{return true;}input = avfilter_inout_alloc();output = avfilter_inout_alloc();bufSrc = avfilter_get_by_name("buffer");rotate = avfilter_get_by_name("rotate");bufSink = avfilter_get_by_name("buffersink");if(NULL == filterGraph || NULL == input || NULL == output){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "alloc failed! :" << endl;return false;}if(NULL == bufSrc || NULL == bufSink){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_get_by_name failed! :" << endl;return false;}snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codecContext0->width, codecContext0->height, codecContext0->pix_fmt, 1, 25, 1, 25); // cout << args << endl;// src 0ret = avfilter_graph_create_filter(&bufSrcContext[0], bufSrc, "in0", args, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// rotatesnprintf(args, sizeof(args), "angle=%f*PI:ow=%d:oh=%d", angle/double(180), codecContext0->width+20*16, codecContext0->height+40*16);cout << args << endl;ret = avfilter_graph_create_filter(&rotateContext, rotate, "rotate", args, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// sinkret = avfilter_graph_create_filter(&bufSinkContext, bufSink, "out", NULL, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}ret = avfilter_link(bufSrcContext[0], 0, rotateContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_link(rotateContext, 0, bufSinkContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_graph_config(filterGraph, NULL);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_config failed! :" << buf << endl;return false;}if(input->next) avfilter_inout_free(&input->next);if(input )avfilter_inout_free(&input);if(output) avfilter_inout_free(&output);return true; }

2、 左右拼接濾鏡

2.1 名稱:hstack
2.2 語法:-inputs:輸出源數量;如:"inputs=2"
2.3 其他:1)拼接后尺寸會變大,為輸入源尺寸的和,buffer in0 + buffer in1;2)引申:上下拼接濾鏡vstack。
2.4 示例代碼

static int initFilter(AVCodecContext * codecContext0, AVCodecContext * codecContext1) {int ret = 0;const AVFilter *bufSrc = NULL;const AVFilter *hstack = NULL;const AVFilter *bufSink = NULL;AVFilterInOut *input = NULL;AVFilterInOut *output = NULL;char args[128] = {0};if(NULL == filterGraph)filterGraph = avfilter_graph_alloc();else{return true;}input = avfilter_inout_alloc();output = avfilter_inout_alloc();bufSrc = avfilter_get_by_name("buffer");hstack = avfilter_get_by_name("hstack");bufSink = avfilter_get_by_name("buffersink");if(NULL == filterGraph || NULL == input || NULL == output){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "alloc failed! :" << endl;return false;}if(NULL == bufSrc || NULL == bufSink){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_get_by_name failed! :" << endl;return false;}snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codecContext0->width, codecContext0->height, codecContext0->pix_fmt, 1, 25, 1, 25);cout << args << endl;// src 0ret = avfilter_graph_create_filter(&bufSrcContext[0], bufSrc, "in0", args, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codecContext0->width, codecContext0->height, codecContext0->pix_fmt, 1, 25, 1, 25);cout << args << endl;// src 1ret = avfilter_graph_create_filter(&bufSrcContext[1], bufSrc, "in1", args, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// hstackret = avfilter_graph_create_filter(&hstackContext, hstack, "hstack", "inputs=2", NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// sinkret = avfilter_graph_create_filter(&bufSinkContext, bufSink, "out", NULL, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}ret = avfilter_link(bufSrcContext[0], 0, hstackContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_link(bufSrcContext[1], 0, hstackContext, 1);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_link(hstackContext, 0, bufSinkContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_graph_config(filterGraph, NULL);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_config failed! :" << buf << endl;return false;}if(input->next) avfilter_inout_free(&input->next);if(input )avfilter_inout_free(&input);if(output) avfilter_inout_free(&output);return true; }

3、水平翻轉濾鏡

3.1 名稱:hflip
3.2 語法:無配置參數
3.3 其他:引申:垂直翻轉濾鏡vflip
3.4 示例代碼

static int initFilter(AVCodecContext * codecContext0, AVCodecContext * codecContext1) {int ret = 0;const AVFilter *bufSrc = NULL;const AVFilter *hflip = NULL;const AVFilter *bufSink = NULL;AVFilterInOut *input = NULL;AVFilterInOut *output = NULL;char args[128] = {0};if(NULL == filterGraph)filterGraph = avfilter_graph_alloc();else{return true;}input = avfilter_inout_alloc();output = avfilter_inout_alloc();bufSrc = avfilter_get_by_name("buffer");hflip = avfilter_get_by_name("hflip");bufSink = avfilter_get_by_name("buffersink");if(NULL == filterGraph || NULL == input || NULL == output){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "alloc failed! :" << endl;return false;}if(NULL == bufSrc || NULL == bufSink){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_get_by_name failed! :" << endl;return false;}snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codecContext0->width, codecContext0->height, codecContext0->pix_fmt, 1, 25, 1, 25);cout << args << endl;// src 0ret = avfilter_graph_create_filter(&bufSrcContext[0], bufSrc, "in0", args, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// hflipret = avfilter_graph_create_filter(&hflipContext, hflip, "hflip", NULL, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// sinkret = avfilter_graph_create_filter(&bufSinkContext, bufSink, "out", NULL, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}ret = avfilter_link(bufSrcContext[0], 0, hflipContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_link(hflipContext, 0, bufSinkContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_graph_config(filterGraph, NULL);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_config failed! :" << buf << endl;return false;}if(input->next) avfilter_inout_free(&input->next);if(input )avfilter_inout_free(&input);if(output) avfilter_inout_free(&output);return true; }

4、邊緣檢測濾鏡

4.1 名稱:edgedetect
4.2 語法: -low:低閾值;-high:高閾值;必須在[0,1]范圍內選擇低閾值和高閾值,低閾值應小于或等于高閾值。-mode:定義繪圖模式,‘wires’:黑白;‘colormix’:類似油畫效果,卡通效果;默認值為wires。舉例:"mode=colormix:low=0.1:high=0.4"
4.3 其他:注意濾鏡輸出格式為GRAY8(wires)、GBR24P(colormix)而非YUV。
4.4 示例代碼

static int initFilter(AVCodecContext * codecContext0, AVCodecContext * codecContext1) {int ret = 0;const AVFilter *bufSrc = NULL;const AVFilter *edgedetect = NULL;const AVFilter *bufSink = NULL;AVFilterInOut *input = NULL;AVFilterInOut *output = NULL;char args[128] = {0};if(NULL == filterGraph)filterGraph = avfilter_graph_alloc();else{return true;}input = avfilter_inout_alloc();output = avfilter_inout_alloc();bufSrc = avfilter_get_by_name("buffer");edgedetect = avfilter_get_by_name("edgedetect");bufSink = avfilter_get_by_name("buffersink");if(NULL == filterGraph || NULL == input || NULL == output){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "alloc failed! :" << endl;return false;}if(NULL == bufSrc || NULL == bufSink){cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_get_by_name failed! :" << endl;return false;}snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codecContext0->width, codecContext0->height, codecContext0->pix_fmt, 1, 25, 1, 25);cout << args << endl;// src 0ret = avfilter_graph_create_filter(&bufSrcContext[0], bufSrc, "in0", args, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// edgedetectret = avfilter_graph_create_filter(&edgedetectContext, edgedetect, "edgedetect", "mode=colormix:low=0.1:high=0.4", NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}// sinkret = avfilter_graph_create_filter(&bufSinkContext, bufSink, "out", NULL, NULL, filterGraph);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_create_filter failed! :" << buf << endl;return false;}ret = avfilter_link(bufSrcContext[0], 0, edgedetectContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_link(edgedetectContext, 0, bufSinkContext, 0);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_link failed! :" << buf << endl;return false;}ret = avfilter_graph_config(filterGraph, NULL);if(0 > ret){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "[" << __FILE__ << "|" << __LINE__ << "]" << "avfilter_graph_config failed! :" << buf << endl;return false;}if(input->next) avfilter_inout_free(&input->next);if(input )avfilter_inout_free(&input);if(output) avfilter_inout_free(&output);return true; }

總結

以上是生活随笔為你收集整理的FFMPEG视频滤镜(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。