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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

FFmpeg Filter基本使用

發布時間:2024/4/11 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FFmpeg Filter基本使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

FFmpeg Filter基本使用


目錄

  • FFmpeg filter簡介
  • filter的使??法
  • filter的語法
  • filterchain的語法
  • filtergraph的語法
  • 基本結構
  • 創建簡單的濾波過程
  • 創建復雜的濾波過程
  • 濾波API
  • ffmpeg中有很多已經實現好的濾波器,這些濾波器的實現位于libavfilter?錄之下,?戶需要進?濾波時,就是是調?這些濾波器來實現的。ffmpeg對于調?濾波器有?整套的調?機制。


    1. FFmpeg filter簡介

  • FFmpeg filter提供了很多?視頻特效處理的功能,?如視頻縮放、截取、翻轉、疊加等。
  • 其中定義了很多的filter,例如以下常?的?些filter。
  • scale:視頻/圖像的縮放
  • overlay:視頻/圖像的疊加
  • crop:視頻/圖像的裁剪
  • trim:截取視頻的?段
  • rotate:以任意?度旋轉視頻
  • ?持的filter的列表可以通過以下命令獲得。
  • ffmpeg -filters
  • 以下是filter的?個簡單的應?示例,對視頻的寬和?減半。
  • ffmpeg -i input -vf scale=iw/2:ih/2 output

    2. filter的使??法

  • 學習filter的使?,先需要了解?下filter的語法。

  • FFmpeg中filter包含三個層次,filter->filterchain->filtergraph。

  • 具體參考下圖:

  • 說明:

  • 第?層是 filter 的語法
  • 第?層是 filterchain的語法。
  • 第三層是 filtergraph的語法
  • filtergraph可以??本形式表示,可以作為ffmpeg中的-filter/-vf/-af和-filter_complex選項以及ffplay中的-vf/-af和libavfilter/avfilter.h中定義的avfilter_graph_parse2()函數的參數。

  • 為了說明可能的情況,我們考慮下?的例?“把視頻的上部分鏡像到下半部分”。

  • 處理流程如下

  • 使?split filter將輸?流分割為兩個流[main]和[temp]。
  • 其中?個流[temp]通過crop filter把下半部分裁剪掉。
  • 步驟2中的輸出再經過vflip filter對視頻進?垂直翻轉,輸出[flip]。
  • 把步驟3中輸出[flip]疊加到[main]的下半部分。
  • 可以?以下的命令來實現這個流程

  • ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT

    1. filter的語法

  • ??個字符串描述filter的組成,形式如下
  • [in_link_1][in_link_N]filter_name=parameters[out_link_1][out_link_M]
    1. 參數說明:
  • [in_link_N]、[out_link_N]:?來標識輸?和輸出的標簽。in_link_N是標簽名,標簽名可以任意命名,需使??括號括起來。在filter_name的前?的標簽?于標識輸?,在filter_name后?的?于標識輸出。?個filter可以有多個輸?和多個輸出,沒有輸?的filter稱為source filter,沒有輸出的filter稱為sink filter。對輸?或輸出打標簽是可選的,打上標簽是為了連接其他filter時使?。

  • filter_name:filter的名稱。

  • “=parameters”:包含初始化filter的參數,是可選的。

  • “=parameters”有以下?種形式

  • 使?’:'字符分隔的?個“鍵=值”對列表。如下所示
  • ffmpeg -i input -vf scale=w=iw/2:h=ih/2 output ffmpeg -i input -vf scale=h=ih/2:w=iw/2 output
  • 使?’:'字符分割的“值”的列表。在這種情況下,鍵按照聲明的順序被假定為選項名。例如,scale filter的前兩個選項分別是w和h,當參數列表為“iw/2:ih/2”時,iw/2的值賦給w,ih/2的值賦給h。如下所示。
  • ffmpeg -i input -vf scale=iw/2:ih/2 output
  • 使?’:’ 字符分隔混合“值”和“鍵=值”對的列表。“值”必須位于“鍵=值”對之前,并遵循與前?點相同的約束順序。之后的“鍵=值”對的順序不受約束。如下所示。
  • ffmpeg -i input -vf scale=iw/2:h=ih/2 output
  • filter類定義了filter的特性以及輸?和輸出的數量,某個filter的使??式可以通過以下命令獲知。

    ffmpeg -h filter=filter_name
  • 以下是rotate filter的使??式

    Filter rotateRotate the input image.slice threading supportedInputs:#0: default (video)Outputs:#0: default (video) rotate AVOptions:angle <string> ..FV.....T set angle (in radians) (default "0")a <string> ..FV.....T set angle (in radians) (default "0")out_w <string> ..FV...... set output width expression (default "iw")ow <string> ..FV...... set output width expression (default "iw")out_h <string> ..FV...... set output height expression (default "ih")oh <string> ..FV...... set output height expression (default "ih")fillcolor <string> ..FV...... set background fill color (default "black")c <string> ..FV...... set background fill color (default "black")bilinear <boolean> ..FV...... use bilinear interpolation (default true)This filter has support for timeline through the 'enable' option.
  • 可以看出它?持slice threading。
  • Inputs下?定義的是輸???梢钥闯鰎otate filter有?個輸?,格式為Video。
  • Outputs下?定義的是輸出。可以看出rotate filter有有?個輸出,格式為video。
  • AVOptions下?定義了?持的參數,后?有默認值描述。為了簡化輸?參數,對?的參數名提供?個簡化的名稱。?如rotate filter中,“angle”的簡化名稱是“a”
  • 以下是使?到fiter的標簽名的?個示例:抽取視頻Y、U、V分量到不同的?件

    ffmpeg -i input.mp4 -filter_complex "extractplanes=y+u+v[y][u][v]" -m ap "[y]" input_y.mp4 -map "[u]" input_u.mp4 -map "[v]" input_v.mp4
  • extractplanes filter指定了三個輸出,分別是 [y][u][v],抽取后,將不同的輸出保存到不同的?件中。

  • 2. filterchain的語法

  • ??個字符串描述filterchain的組成,形式如下
  • "filter1, filter2, ... filterN-1, filterN"
  • 說明:
  • 由?個或多個filter的連接?成,filter之間以逗號“,”分隔。
  • 每個filter都連接到序列中的前?個filter,即前?個filter的輸出是后?個filter的輸?。?如示例
  • ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
  • 示例說明: crop、vflip在同?個filterchain中
  • 3. filtergraph的語法

  • ??個字符串描述filtergraph的組成,形式如下
  • "filterchain1;filterchain2;...filterchainN-1;fiterchainN"
  • 由?個或多個filter的組合?成,filterchain之間?分號";"分隔。
  • filtergraph是連接filter的有向圖。它可以包含循環,?對filter之間可以有多個連接。
  • 當在filtergraph中找到兩個相同名稱的標簽時,將創建相應輸?和輸出之間的連接。
  • 如果輸出沒有被打標簽,則默認將其連接到filterchain中下?個filter的第?個未打標簽的輸?。例如以下filterchain中
  • nullsrc, split[L1], [L2]overlay, nullsink
  • 說明:split filter有兩個輸出,overlay filter有兩個輸?。split的第?個輸出標記為“L1”,overlay的第?個輸?pad標記為“L2”。split的第?個輸出將連接到overlay的第?個輸?。
  • 在?個filter描述中,如果沒有指定第?個filter的輸?標簽,則假定為“In”。如果沒有指定最后?個filter的輸出標簽,則假定為“out”。
  • 在?個完整的filterchain中,所有沒有打標簽的filter輸?和輸出必須是連接的。如果所有filterchain的所有filter輸?和輸出pad都是連接的,則認為filtergraph是有效的
  • ?如示例
  • ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
  • 其中有三個filterchain, 分別是:
  • “split [main][tmp]”。它只有?個filter,即 split,它有?個默認的輸?,即INPUT解碼后的frame。有兩個輸出, 以 [main], [tmp] 標識。
  • “[tmp] crop=iw:ih/2:0:0, vflip [flip]”。它由兩個filter組成,crop和vflip,crop的輸? 為[tmp],vflip的輸出標識為[flip]。
  • “[main][flip] overlay=0:H/2”。它由?個filter組成,即overlay。有兩個輸?,[main]和[flip]。有?個默認的輸出。

  • 3. 基本結構

  • 我們把?整個濾波的流程稱為濾波過程。下?是?個濾波過程的結構
  • 圖中簡要指示出了濾波所?到的各個結構體,各個結構體有如下作?:
  • 名稱作用
    AVFilterGraph?于統合這整個濾波過程的結構體。
    AVFilter濾波器,濾波器的實現是通過AVFilter以及位于其下的結構體/函數來維護的。
    AVFilterContext?個濾波器實例,即使是同?個濾波器,但是在進?實際的濾波時,也會由于輸?的參數不同?有不同的濾波效果,AVFilterContext就是在實際進?濾波時?于維護濾波相關信息的實體。
    AVFilterLink濾波器鏈,作?主要是?于連接相鄰的兩個AVFilterContext。為了實現?個濾波過程,可能會需要多個濾波器協同完成,即?個濾波器的輸出可能會是另?個濾波器的輸?,AVFilterLink的作?是串聯兩個相鄰的濾波器實例,形成兩個濾波器之間的通道。
    AVFilterPad濾波器的輸?輸出端?,?個濾波器可以有多個輸?以及多個輸出端?,相鄰濾波器之間是通過AVFilterLink來串聯的,?位于AVFilterLink兩端的分別就是前?個濾波器的輸出端?以及后?個濾波器的輸?端?。
    buffersrc?個特殊的濾波器,這個濾波器的作?就是充當整個濾波過程的??,通過調?該濾波器提供的函數(如av_buffersrc_add_frame)可以把需要濾波的幀傳輸進?濾波過程。在創建該濾波器實例的時候需要提供?些關于所輸?的幀的格式的必要參數(如:time_base、圖像的寬?、圖像像素格式等)。
    buffersink?個特殊的濾波器,這個濾波器的作?就是充當整個濾波過程的出?,通過調?該濾波器提供的函數(如av_buffersink_get_frame)可以提取出被濾波過程濾波完成后的幀。

    4. 創建簡單的濾波過程

  • 創建整個濾波過程包含以下步驟:
  • ?先需要得到整個濾波過程所需的濾波器(AVFilter),其中buffersrc以及buffersink是作為輸?以及輸出所必須的兩個濾波器。
  • const AVFilter *buffersrc = avfilter_get_by_name("buffer"); const AVFilter *buffersink = avfilter_get_by_name("buffersink"); const AVFilter *myfilter = avfilter_get_by_name("myfilter");
  • 創建統合整個濾波過程的濾波圖結構體(AVFilterGraph)
  • filter_graph = avfilter_graph_alloc();
  • 創建?于維護濾波相關信息的濾波器實例(AVFilterContext)
  • AVFilterContext *in_video_filter = NULL; AVFilterContext *out_video_filter = NULL; AVFilterContext *my_video_filter = NULL; avfilter_graph_create_filter(&in_video_filter, buffersrc, "in", args,NULL, filter_graph); avfilter_graph_create_filter(&out_video_filter, buffersink, "out", NULL, NULL, filter_graph); avfilter_graph_create_filter(&my_video_filter, myfilter, "myfilter", NULL, NULL, filter_graph);
  • ?AVFilterLink把相鄰的兩個濾波實例連接起來
  • avfilter_link(in_video_filter, 0, my_video_filter, 0); avfilter_link(my_video_filter, 0, out_video_filter, 0);
  • 提交整個濾波圖
  • avfilter_graph_config(filter_graph, NULL);

    5. 創建復雜的濾波過程

  • 當濾波過程復雜到?定程度時,即需要多個濾波器進?復雜的連接來實現整個濾波過程,這時候對于調?者來說,繼續采?上述?法來構建濾波圖就顯得不夠效率。對于復雜的濾波過程,ffmpeg提供了?個更為?便的濾波過程創建?式。
  • 這種復雜的濾波器過程創建?式要求?戶以字符串的?式描述各個濾波器之間的關系。如下是?個描述復雜濾波過程的字符串的例?:
  • [0]trim=start_frame=10:end_frame=20[v0];\ [0]trim=start_frame=30:end_frame=40[v1];\ [v0][v1]concat=n=2[v2];\ [1]hflip[v3];\ [v2][v3]overlay=eof_action=repeat[v4];\ [v4]drawbox=50:50:120:120:red:t=5[v5]
  • 以上是?個連續的字符串,為了?便分析我們把該字符串進?了劃分,每??都是?個濾波器實例,對于??:

  • 開頭是?對中括號,中括號內的是輸?的標識名0。
  • 中括號后?接著的是濾波器名稱trim。
  • 名稱后的第?個等號后?是濾波器參數start_frame=10:end_frame=20,這?有兩組參數,兩組參數?冒號分開。
  • 第?組參數名稱為start_frame,參數值為10,中間?等號分開。
  • 第?組參數名稱為end_frame,參數值為20,中間?等號分開。
  • 最后也有?對中括號,中括號內的是輸出的標識名v0。
  • 如果?個濾波實例的輸?標識名與另?個濾波實例的輸出標識名相同,則表示這兩個濾波實例構成濾波鏈。
  • 如果?個濾波實例的輸?標識名或者輸出標識名?直沒有與其它濾波實例的輸出標識名或者輸?標識名相同,則表明這些為外部的輸?輸出,通常我們會為其接上buffersrc以及buffersink。
  • 按照這種規則,上?的濾波過程可以被描繪成以下濾波圖

  • ffmpeg提供?個函數?于解析這種字符串:avfilter_graph_parse2。這個函數會把輸?的字符串?成如上?的濾波圖,不過我們需要???成buffersrc以及buffersink的實例,并通過該函數提供的輸?以及輸出接?把buffersrc、buffersink與該濾波圖連接起來。整個流程包含以下步驟

  • 創建統合整個濾波過程的濾波圖結構體(AVFilterGraph)
  • filter_graph = avfilter_graph_alloc();
  • 解析字符串,并構建該字符串所描述的濾波圖
  • avfilter_graph_parse2(filter_graph, graph_desc, &inputs, &outputs);
  • 其中inputs與outputs分別為輸?與輸出的接?集合,我們需要為這些接?接上輸?以及輸出
  • for (cur = inputs, i = 0; cur; cur = cur->next, i++) {const AVFilter *buffersrc = avfilter_get_by_name("buffer");avfilter_graph_create_filter(&filter, buffersrc, name, args, NULL, filter_graph);avfilter_link(filter, 0, cur->filter_ctx, cur->pad_idx);}avfilter_inout_free(&inputs);for (cur = outputs, i = 0; cur; cur = cur->next, i++) {const AVFilter *buffersink = avfilter_get_by_name("buffersink");avfilter_graph_create_filter(&filter, buffersink, name, NULL, NULL, filter_graph);avfilter_link(cur->filter_ctx, cur->pad_idx, filter, 0);}avfilter_inout_free(&outputs);
  • 提交整個濾波圖
  • avfilter_graph_config(filter_graph, NULL);

    6. 濾波API

  • 上?主要討論了如何創建濾波過程,不過要進?濾波還需要把幀傳輸進?該過程,并在濾波完成后從該過程中提取出濾波完成的幀。
  • buffersrc提供了向濾波過程輸?幀的API:av_buffersrc_add_frame。向指定的buffersrc實例輸?想要進?濾波的幀就可以把幀傳?濾波過程。
  • av_buffersrc_add_frame(c->in_filter, pFrame);
  • buffersink提供了從濾波過程提取幀的API:av_buffersink_get_frame??梢詮闹付ǖ腷uffersink實例提取濾波完成的幀。
  • av_buffersink_get_frame(c->out_filter, pFrame);
  • 當av_buffersink_get_frame返回值?于0則表示提取成功。
  • 總結

    以上是生活随笔為你收集整理的FFmpeg Filter基本使用的全部內容,希望文章能夠幫你解決所遇到的問題。

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