使用ffmpeg的filter處理yuv數據包括split filter(分流)、crop filter(裁剪)、vflip filter(垂直向上的翻轉)、overlay filter(合成)

使用ffmpeg的filter處理yuv數據包括split filter(分流)、crop filter(裁剪)、vflip filter(垂直向上的翻轉)、overlay filter(合成)

#include <stdio.h>#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>int main()
{printf("Hello video mark!\n");int ret = 0;FILE* infile = NULL;const char* infileName = "768x320.yuv";fopen_s(&infile, infileName, "rb+");if(!infile){printf("fopen_s() infile failed!\n");return -1;}int in_width = 768;int in_height = 320;FILE* outfile = NULL;const char* outfileName = "out_mark.yuv";fopen_s(&outfile, outfileName, "wb");if(!outfile){printf("fopen_s() outfile failed!\n");return -1;}//注冊初始化所有過濾器avfilter_register_all();//用于整個過濾流程的一個封裝AVFilterGraph* filter_grah = avfilter_graph_alloc();if(!filter_grah){printf("avfilter_graph_alloc() failed!\n");return -1;}char args[512];sprintf(args,"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",in_width, in_height, AV_PIX_FMT_YUV420P,1, 25, 1, 1);//獲取一個用于AVFilterGraph輸入的過濾器AVFilter* buffersSrc = avfilter_get_by_name("buffer");AVFilterContext* bufferSrc_ctx;//將bufferSrc添加到AVFilterGraph中//args是用在bufferSrc的參數ret = avfilter_graph_create_filter(&bufferSrc_ctx, buffersSrc,"in", args, NULL, filter_grah);if(ret < 0){printf("avfilter_graph_create_filter() buffersSrc failed!\n");return -1;}AVBufferSinkParams* bufferSinkParams;AVFilterContext* bufferSink_ctx;//獲取一個用于AVFilterGraph輸出的過濾器AVFilter* bufferSink = avfilter_get_by_name("buffersink");enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE};bufferSinkParams = av_buffersink_params_alloc();bufferSinkParams->pixel_fmts = pix_fmts;ret = avfilter_graph_create_filter(&bufferSink_ctx, bufferSink,"out", NULL, bufferSinkParams, filter_grah);if(ret < 0){printf("avfilter_graph_create_filter() bufferSink failed!\n");return -1;}//split filter(分流)AVFilter* splitFilter = avfilter_get_by_name("split");AVFilterContext* splitFilter_ctx;//outputs=2 分流2通道ret = avfilter_graph_create_filter(&splitFilter_ctx, splitFilter, "split","outputs=2", NULL, filter_grah);if(ret < 0){printf("avfilter_graph_create_filter() splitFilter failed!\n");return -1;}//crop filter(裁剪)AVFilter* cropFilter = avfilter_get_by_name("crop");AVFilterContext* cropFilter_ctx;ret = avfilter_graph_create_filter(&cropFilter_ctx, cropFilter, "crop","out_w=iw:out_h=ih/2:x=0:y=0", NULL, filter_grah);if(ret < 0){printf("avfilter_graph_create_filter() cropFilter failed!\n");return -1;}//vflip filter(垂直向上的翻轉)AVFilter* vflipFilter = avfilter_get_by_name("vflip");AVFilterContext* vflipFilter_ctx;ret = avfilter_graph_create_filter(&vflipFilter_ctx, vflipFilter, "vflip",NULL, NULL, filter_grah);if(ret < 0){printf("avfilter_graph_create_filter() vflipFilter failed!\n");return -1;}//overlay filter(合成)AVFilter* overlayFilter = avfilter_get_by_name("overlay");AVFilterContext* overlayFilter_ctx;ret = avfilter_graph_create_filter(&overlayFilter_ctx, overlayFilter, "overlay","y=0:H/2", NULL, filter_grah);if(ret < 0){printf("avfilter_graph_create_filter() overlayFilter failed!\n");return -1;}//srcFilter -> splitFilter//srcpad、dstpad是一個索引,通道的索引ret = avfilter_link(bufferSrc_ctx, 0, splitFilter_ctx, 0);if(ret != 0){printf("avfilter_link() srcFilter -> splitFilter failed!\n");return -1;}//splitFilter[0] -> overlayfilter[0]ret = avfilter_link(splitFilter_ctx, 0, overlayFilter_ctx, 0);if(ret != 0){printf("avfilter_link() splitFilter[0] -> overlayfilter[0] failed!\n");return -1;}//splitFilter[1] -> cropFilterret = avfilter_link(splitFilter_ctx, 1, cropFilter_ctx, 0);if(ret != 0){printf("avfilter_link() splitFilter[1] -> cropFilter failed!\n");return -1;}
\//cropFilter -> vflipFilterret = avfilter_link(cropFilter_ctx, 0, vflipFilter_ctx, 0);if(ret != 0){printf("avfilter_link() cropFilter -> vflipFilter failed!\n");return -1;}//vflipFilter -> overlayfilter[1]ret = avfilter_link(vflipFilter_ctx, 0, overlayFilter_ctx, 1);if(ret != 0){printf("avfilter_link() vflipFilter -> overlayfilter[1] failed!\n");return -1;}//overlayfilter -> bufferSinkret = avfilter_link(overlayFilter_ctx, 0, bufferSink_ctx, 0);if(ret != 0){printf("avfilter_link() overlayfilter -> bufferSink failed!\n");return -1;}//確認所有過濾器的連接ret = avfilter_graph_config(filter_grah, NULL);if(ret < 0){printf("avfilter_graph_config() failed!\n");return -1;}//打印filtergraph的信息char* graph_str = avfilter_graph_dump(filter_grah, NULL);printf("\n%s\n", graph_str);av_free(graph_str);//輸入幀AVFrame* frame_in = av_frame_alloc();unsigned char* frame_buffer_in = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, in_width, in_height, 1));//輸出幀AVFrame* frame_out = av_frame_alloc();frame_in->width = in_width;frame_in->height = in_height;frame_in->format = AV_PIX_FMT_YUV420P;uint32_t frame_size = in_width * in_height * 3 / 2;while (1){//讀取yuv數據if(fread(frame_buffer_in, 1, frame_size, infile) != frame_size){break;}av_image_fill_arrays(frame_in->data, frame_in->linesize, frame_buffer_in, AV_PIX_FMT_YUV420P, in_width, in_height, 1);//添加幀數據到過濾器if(av_buffersrc_add_frame(bufferSrc_ctx, frame_in) < 0){printf("av_buffersrc_add_frame() failed!\n");break;}//獲取輸出幀數據ret = av_buffersink_get_frame(bufferSink_ctx, frame_out);if(ret < 0){printf("av_buffersink_get_frame() failed!\n");break;}//輸出文件if(frame_out->format == AV_PIX_FMT_YUV420P){for (int i = 0; i < frame_out->height; i++) {fwrite(frame_out->data[0] + frame_out->linesize[0] * i, 1, frame_out->width, outfile);}for (int i = 0; i < frame_out->height / 2; i++) {fwrite(frame_out->data[1] + frame_out->linesize[1] * i, 1, frame_out->width / 2, outfile);}for (int i = 0; i < frame_out->height / 2; i++) {fwrite(frame_out->data[2] + frame_out->linesize[2] * i, 1, frame_out->width / 2, outfile);}}av_frame_unref(frame_out);}fclose(infile);fclose(outfile);av_frame_free(&frame_in);av_frame_free(&frame_out);avfilter_graph_free(&filter_grah);printf("end video mark!\n");return 0;
}```

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379083.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379083.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379083.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vc++ 6.0 堆棧_在C ++中使用鏈接列表實現堆棧

vc 6.0 堆棧To implement a stack using a linked list, basically we need to implement the push() and pop() operations of a stack using linked list. 要使用鏈接列表實現堆棧 &#xff0c;基本上&#xff0c;我們需要使用鏈接列表實現堆棧的push()和pop()操作。 Exampl…

煙雨小書店

煙雨小書店演示視頻 源碼

協議地址結構_TCP/IP 協議 講解

計算機網絡體系結構分層太厲害了&#xff0c;終于有人能把TCP/IP 協議講的明明白白了計算機網絡體系結構分層不難看出&#xff0c;TCP/IP 與 OSI 在分層模塊上稍有區別。OSI 參考模型注重“通信協議必要的功能是什么”&#xff0c;而 TCP/IP 則更強調“在計算機上實現協議應該開…

ffmpeg進行混音,將兩路音頻pcm數據合成一路輸出

ffmpeg進行混音&#xff0c;將兩路音頻pcm數據合成一路輸出 audiomixer.h #ifndef AUDIOMIXER_H #define AUDIOMIXER_H#include <map> #include <mutex> #include <cstdio> #include <cstdint> #include <string> #include <memory>exter…

python sep函數_Python中帶有print()函數的sep參數

python sep函數sep parameter stands for separator, it uses with the print() function to specify the separator between the arguments. sep參數代表分隔符&#xff0c;它與print()函數一起使用以指定參數之間的分隔符。 The default value is space i.e. if we dont us…

關于 MySQL 主從復制的配置(轉)

來源&#xff1a;http://www.oschina.net/bbs/thread/10388設置Mysql的主從設置很重要&#xff0c;有如下幾點用處&#xff1a;1 做備份機器&#xff0c;一旦主服務器崩潰&#xff0c;可以直接啟用從服務器作為主服務器2 可以直接鎖定從服務器的表只讀&#xff0c;然后做備份數…

Silverlight 同域WCF免跨域文件

在sl3使用wcf時常常會因為sl中調用了不同域的wcf服務而導至調用服務失敗&#xff0c;記得在很久以前sl當是只支持同域的訪問&#xff0c;那么讓我有一個想法&#xff0c;就是在sl引用時可以動態地取得當前sl所在的域&#xff0c;而wcf服務也必須同時部署到這個域下邊&#xff0…

使用ffmpeg 的 filter 給圖片添加水印

使用ffmpeg 的 filter 給圖片添加水印。 main.c #include <stdio.h>#include <libavfilter/avfilter.h> #include <libavfilter/buffersrc.h> #include <libavfilter/buffersink.h> #include <libavformat/avformat.h> #include <libavcodec…

程序崩潰 分析工具_程序分析工具| 軟件工程

程序崩潰 分析工具A program analysis tool implies an automatic tool that takes the source code or the executable code of a program as information and produces reports with respect to a few significant attributes of the program, for example, its size, multif…

28335接兩個spi設備_IIC和SPI如此流行,誰才是嵌入式工程師的必備工具?

IICvs SPI現今&#xff0c;在低端數字通信應用領域&#xff0c;我們隨處可見 IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是這兩種通信協議非常適合近距離低速芯片間通信。Philips(for IIC)和 Motorola(for SPI) 出于不同背景和市場需求…

線性表15|魔術師發牌問題和拉丁方陣 - 數據結構和算法20

線性表15 : 魔術師發牌問題和拉丁方陣 讓編程改變世界 Change the world by program 題外話 今天小甲魚看到到微博有朋友在問&#xff0c;這個《數據結構和算法》系列課程有木有JAVA版本的&#xff1f; 因為這個問題之前也有一些朋友問過&#xff0c;所以咱在這里統一說下哈…

[ZT]Three ways to tell if a .NET Assembly is Strongly Named (or has Strong Name)

Here are several convenient ways to tell whether a .NET assembly is strongly named. (English language note: I assume the form “strongly named” is preferred over “strong named” since that’s the form used in the output of the sn.exe tool shown immediat…

最佳頁面置換算法

在一個請求分頁系統中&#xff0c;采用最佳頁面置換算法時&#xff0c;假如一個作業的頁面走向為4、3、2、1、4、3、5、4、3、2、1、5&#xff0c;當分配給該作業的物理塊數M分別為3和4時&#xff0c;試計算在訪問過程中所發生的缺頁次數和缺頁率。請給出分析過程。 解析&…

網絡名稱 轉換 網絡地址_網絡地址轉換| 計算機網絡

網絡名稱 轉換 網絡地址At the time of classful addressing, the number of household users and small businesses that want to use the Internet kept increasing. In the beginning, a user was connected to the Internet with a dial-up line, for a specific period of…

rstudio 修改代碼間距_第一章 R和RStudio

R與RStudioR是一種統計學編程語言&#xff0c;在科學計算領域非常流行。它是由Ross Ihaka和Robert Gentleman開發的&#xff0c;是 "S "編程語言的開源實現。R也是使用這種語言進行統計計算的軟件的名字。它有一個龐大的在線支持社區和專門的軟件包&#xff0c;可以為…

ubuntu下最穩定的QQ

一、安裝好 Wine 1.2&#xff08;1.2 版安裝好就支持中文界面的了&#xff09; 當然得有WINE 了 當然我的有 如果沒有可以如下方法得到&#xff1a; 第一種方法&#xff1a;如果你已經安裝過 Wine 的老版本&#xff0c;那么只要添加 Wine 1.2 的軟件源&#xff0c;然后去新立得…

字體Times New Roman

Windows系統中的字體是Monotype公司為微軟公司制作的Times New Roman PS&#xff08;TrueType字體&#xff09;&#xff0c;視窗系統從3.1版本開始就一直附帶這個字體。而在蘋果電腦公司的麥金塔系統中使用的是Linotype公司的 Times Roman (在Macintosh系統中直接簡稱為‘Times…

最近最久未使用頁面置換算法

在一個請求分頁系統中&#xff0c;采用最近最久未使用頁面置換算法時&#xff0c;假如一個作業的頁面走向為4、3、2、1、4、3、5、4、3、2、1、5&#xff0c;當分配給該作業的物理塊數M分別為3和4時&#xff0c;試計算在訪問過程中所發生的缺頁次數和缺頁率。請給出分析過程。 …